Geschwindigkeit

  • Hi Leute, ich habe da mal eine Frage:
    ich habe eine Datei, die 198706 Wörter (bei 2266243 Zeichen) enthält, vorliegen. Jedes Wort in dieser Datei steht in einer Zeile. All diese Wörter sollen auf eine gewisse Regelmäsigkeit mit einem eingegebenen Wort untersucht werden (gleiche Endbuchstaben). Ich lese die Wörter aus der großen Datei mittels Filereadline ein. Soweit funktioniert alles. Nur ist das Ganze elend langsam. Bis das Programm alle Wörter überprüft hat, ist eine geraume Zeit vergangen (locker eine Stunde!). Da ich noch weitere Dinge zum Überprüfen ergänzen muss, auf die das Wort überprüft wird, geht später alles warscheinlich noch langsamer.

    Hat irgendwer eine Idee, wie ich den ganzen vorganz beschleunigen kann? Ich wäre euch echt sehr dankbar, wenn ihr mir einen Tipp geben könntet.

  • Kann es sein, dass 65525 die maximale Anzahl der Rows im Arrys ist? Das ist zu wenig... Denn schaut mal:

    [autoit]

    $a=stringsplit(fileread("wörter.txt"),@CR)
    _arraydisplay($a)

    [/autoit]

    zeig das da an:
    [Blockierte Grafik: http://s1.directupload.net/images/120207/62tupq8o.jpg]

  • "Arrays: A maximum of 64 dimensions and/or a total of 16 million elements
    Maximum depth of recursive function calls: 5100 levels"

    wohl kaum:D

    warum benützt du nicht einfach _FileReadToArray()?

  • Hi,
    kann sein, dass ich das Problem nicht ganz begriffen habe...
    Die Wörter in der Datei sind doch durch CRLF getrennt.
    Datei öffnen
    $dateiinhalt=fileread("wörter.txt"),
    per stringinstr($dateiinhalt,$gleichewortendung&@CRLF) suchen?

  • Naja, so einfach ist das nicht... Ich brauche einerseits die Wörter, die die Überprüfung bestanden haben und dann muss ich dieses Wort nochmal auf verschiedene Dinge nochmal überpüfen (z.B. Aufreten von Vokalen...)

  • Zitat

    Naja, so einfach ist das nicht.

    doch, wetten? 8)

    Zitat

    .. Ich brauche einerseits die Wörter, die die Überprüfung bestanden haben und dann muss ich dieses Wort nochmal auf verschiedene Dinge nochmal überpüfen (z.B. Aufreten von Vokalen...)


    Dann stell doch einfach mal dein Script ein, damit man KONKRET helfen kann...

  • EDIT: Habs jetzt nochmal bissle umgeschrieben, braucht jetzt ca. 1 Sekunde bei 200000 Wörtern:
    EDIT2: Jetzt aber... Ich hab den Edit-Button oft genug penetriert...

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aSource
    _FileReadToArray("file.txt", $aSource)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "", $aSource[0] & " Wörter...")

    [/autoit] [autoit][/autoit] [autoit]

    Global $Timer = TimerInit(), $aSearch
    $aSearch = _ArrayRegExp($aSource, '(?i)e$') ; ohne (?i) falls Case-Sensitive
    MsgBox(0, "", "Berechnung fertig (" & Round(TimerDiff($Timer)) & " ms), _arraydisplay() braucht ne Weile:D")
    _ArrayDisplay($aSearch)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _ArrayRegExp(Const ByRef $aArray, $sPattern)
    If Not IsArray($aArray) Then Return SetError(1, 0, -1)
    Dim $aResults[UBound($aArray)], $iIndex = 1
    For $iI = 1 To UBound($aArray)-1 Step 1
    If StringRegExp($aSource[$iI], $sPattern) Then
    $aResults[$iIndex] = $aSource[$iI]
    $iIndex +=1
    EndIf
    Next
    ReDim $aResults[$iIndex]
    $aResults[0] = $iIndex-1
    Return $aResults
    EndFunc

    [/autoit]
    Zitat

    You just keep on trying 'till you run out of cake. ;)


    [STEAM] Source UDF

    8 Mal editiert, zuletzt von K4z (8. Februar 2012 um 00:05)

  • Was hält dich davon ab das Skript jetzt reinzustellen?
    So könnte man dir mal konkret helfen und du hast vielleicht sogar noch heute ein noch viel besseres Skript.
    Kann aber halt nur richtig gemacht werden wenn man die potentiell Helfenden, wie es die letzten 12 Posts geschehen ist, nicht im Dunkeln stochern lässt.

  • Was mich davon abhält? Das Script liegt (ebenso wie die Wörterliste) nicht auf einem anderen PC und an den komme ich leider erst wieder morgen Dran. Tut mir Leid... Aber morgen poste ich dann von mmir aus mein Script.

  • Hi, ich habe nun das Script von K4z verwendet und es funktionier alles bestens - an dieser Stelle ein riesengroßes Danke. Die Geschwindigkeit ist mit etwas unter 1,6 Sekunden sehr gut. Danke für all eure Hilfen!

  • öÖ gerade fällt mir auf, dass K4z Script mir einige Wörter unterschlägt (Gibt nur 38464 Wörter aus)... Ich poste hier jetzt mal mein bisheriges Script:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <File.au3>
    GUICreate("", 338, 369)
    GUICtrlCreateLabel("Zu prüfendes Wort:", 8, 8, 310, 17)
    $_Wort = GUICtrlCreateInput("", 16, 32, 225, 21)
    $_Loesungen = GUICtrlCreateEdit("", 8, 104, 321, 225)
    GUICtrlSetData(-1, "Ergebnise:" & @CRLF)
    $_Status = GUICtrlCreateLabel(":", 8, 344,999,13)
    $_Suche = GUICtrlCreateButton("Suche", 8, 72)
    GUISetState(@SW_SHOW)

    [/autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $_Suche
    $Wort = GUICtrlRead ($_Wort)
    GUICtrlSetData ($_Status,"Lese Wörterliste ein...")
    Dim $aSource
    Dim $Wortanzahl
    _FileReadToArray("wörter.txt", $aSource)
    $Wortanzahl = $aSource[0]
    GUICtrlSetData ($_Status,"Verarbeite eingelesene Wörterliste...")
    Global $time = TimerInit(), $aSearch
    $aSearch = _ArrayRegExp($aSource, '()e

    [autoit][/autoit][autoit]

    Edit: Ich habe es jetzt mit Fileread und Stringsplit gemacht. Das ist einfacher und geht sogar schneller. Das Problem sollte damit gelöst sein. Nochmal danke an euch alle! So sieht mein Script jetzt aus:
    [autoit]#include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <File.au3>
    GUICreate("", 338, 369)
    GUICtrlCreateLabel("Zu prüfendes Wort:", 8, 8, 310, 17)
    $_Wort = GUICtrlCreateInput("", 16, 32, 225, 21)
    $_Loesungen = GUICtrlCreateEdit("", 8, 104, 321, 225)
    GUICtrlSetData(-1, "Ergebnise:" & @CRLF)
    $_Status = GUICtrlCreateLabel(":", 8, 344,999,13)
    $_Suche = GUICtrlCreateButton("Suche", 8, 72)
    GUISetState(@SW_SHOW)

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $_Suche
    $Wort = GUICtrlRead ($_Wort)
    $wortendung = StringRight ($Wort,3)
    $time = TimerInit ()
    $text = StringSplit (FileRead ("wörter.txt"),@CR)
    For $i = 1 To $text[0] Step 1
    If StringRight ($text[$i],3) = $wortendung Then
    GUICtrlSetData ($_Loesungen,GUICtrlRead ($_Loesungen) & @CRLF & $text[$i])
    EndIf
    Next

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]GUICtrlSetData ($_Status,"Die Suche wurde nach " & Round (TimerDiff ($time) / 1000,2) & " Sekunden abgeschlossen.")
    EndSwitch
    WEnd

    [/autoit]

    ) ; ohne (?i) falls Case-Sensitive
    GUICtrlSetData ($_Status,"Suche Wörter...")
    $wortendung = StringRight ($Wort,3)
    ; _ArrayDisplay ($aSearch)
    For $i = 1 To 38464 Step 1
    If StringRight ($aSearch[$i],3) = $wortendung Then
    GUICtrlSetData ($_Loesungen,GUICtrlRead ($_Loesungen) & @CRLF & $aSearch[$i])
    EndIf
    Next [/autoit]

    [autoit][/autoit][autoit]

    MsgBox (64,"","Die Suche wurde nach " & Round (TimerDiff ($time) / 1000,2) & " Sekunden abgeschlossen.")
    GUICtrlSetData ($_Status,"Fertig")
    EndSwitch
    WEnd

    [/autoit][autoit][/autoit][autoit]

    ; Funktioniert nicht ganz
    Func _ArrayRegExp(Const ByRef $aArray, $sPattern)
    If Not IsArray($aArray) Then Return SetError(1, 0, -1)
    Dim $aResults[UBound($aArray)], $iIndex = 1
    For $iI = 1 To UBound($aArray)-1 Step 1
    If StringRegExp($aSource[$iI], $sPattern) Then
    $aResults[$iIndex] = $aSource[$iI]
    $iIndex +=1
    EndIf
    Next
    ReDim $aResults[$iIndex]
    $aResults[0] = $iIndex-1
    Return $aResults
    EndFunc

    [/autoit]

    [/spoiler]

    Edit: Ich habe es jetzt mit Fileread und Stringsplit gemacht. Das ist einfacher und geht sogar schneller. So sieht mein Script jetzt aus:

    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <File.au3>
    GUICreate("", 338, 369)
    GUICtrlCreateLabel("Zu prüfendes Wort:", 8, 8, 310, 17)
    $_Wort = GUICtrlCreateInput("", 16, 32, 225, 21)
    $_Loesungen = GUICtrlCreateEdit("", 8, 104, 321, 225)
    GUICtrlSetData(-1, "Ergebnise:" & @CRLF)
    $_Status = GUICtrlCreateLabel(":", 8, 344,999,13)
    $_Suche = GUICtrlCreateButton("Suche", 8, 72)
    GUISetState(@SW_SHOW)

    [/autoit][autoit][/autoit][autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $_Suche
    $Wort = GUICtrlRead ($_Wort)
    $wortendung = StringRight ($Wort,3)
    $time = TimerInit ()
    $text = StringSplit (FileRead ("wörter.txt"),@CR)
    For $i = 1 To $text[0] Step 1
    If StringRight ($text[$i],3) = $wortendung Then
    GUICtrlSetData ($_Loesungen,GUICtrlRead ($_Loesungen) & @CRLF & $text[$i])
    EndIf
    Next

    [/autoit][autoit][/autoit][autoit]

    GUICtrlSetData ($_Status,"Die Suche wurde nach " & Round (TimerDiff ($time) / 1000,2) & " Sekunden abgeschlossen.")
    EndSwitch
    WEnd

    [/autoit]
  • Also bei mir unterschlägt es keine Wörter, Notepad++ findet genauso viele Wörter, egal was ich eingeb.....
    Man sollt halt die Regular Expression richtig verwenden, dann gehts auch

  • Hi,
    hab mal CheaterDieters Script bissl aufgemotzt, läuft bei mir ca. 30-40x schneller als das "Orginal"

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $text = FileRead ("wörter.txt")
    $loesung=""
    GUICreate("", 338, 369)
    GUICtrlCreateLabel("Zu prüfendes Wort:", 8, 8, 310, 17)
    $_Wort = GUICtrlCreateInput("", 16, 32, 225, 21)
    $_Loesungen = GUICtrlCreateEdit("", 8, 104, 321, 225)
    GUICtrlSetData(-1, "Ergebnise:" & @CRLF)
    $_Status = GUICtrlCreateLabel(":", 8, 344,999,13)
    $_Suche = GUICtrlCreateButton("Suche", 8, 72)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $_Suche
    $Wort = GUICtrlRead ($_Wort)
    $wortendung = StringRight ($Wort,3)&@CRLF
    $pos=1
    $time = TimerInit ()
    while $pos<>0
    $pos=StringInStr($text,$wortendung,1,1,$pos+3);position letzte 3 buchstaben finden
    $pos0=StringInStr($text,@crlf,1,-1,$pos);position wortanfang finden
    $loesung&=stringmid($text,$pos0,$pos-$pos0+3)
    wend
    GUICtrlSetData ($_Status,"Die Suche wurde nach " & Round (TimerDiff ($time) / 1000,2) & " Sekunden abgeschlossen.")
    GUICtrlSetData ($_Loesungen,$loesung)
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ;Orginal
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $_Suche
    $Wort = GUICtrlRead ($_Wort)
    $wortendung = StringRight ($Wort,3)
    $time = TimerInit ()
    $text = StringSplit (FileRead ("wörter.txt"),@CR)
    For $i = 1 To $text[0] Step 1
    If StringRight ($text[$i],3) = $wortendung Then
    GUICtrlSetData ($_Loesungen,GUICtrlRead ($_Loesungen) & @CRLF & $text[$i])
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData ($_Status,"Die Suche wurde nach " & Round (TimerDiff ($time) / 1000,2) & " Sekunden abgeschlossen.")
    EndSwitch
    WEnd

    [/autoit]

    /EDIT/ wesentlich schneller, wenn casesensitiv gesucht wird...

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (8. Februar 2012 um 21:16)