Script zu langsam

  • Hallo Zusammen

    Kann man dieses Script irgenwie umschreiben, damit es schneller geht? Leider ist die Liste im .txt File grösser als das Array erlaubt.

    I wünsche euch allen ein gutes 2021.

    Grüsse

    Chaspel

    Einmal editiert, zuletzt von Chaspel (31. Dezember 2020 um 12:04)

  • Hi,

    wieder mal ein schönes Beispiel für ein XY-Problem...

    Kein Mensch braucht ein Array mit derartig vielen "Zeilen" aus einer Textdatei, die mittels FilereadLine ausgelesen werden müssen!

    Eine beliebig große Datei in ein Array liest man innerhalb von Millisekunden ein. Textdatei öffnen, mittels StringSplit() in ein Array packen, fertig.

    Zeig mal die Anwendung, für die man diese Konstruktion überhaupt benötigt.

    Und auch mal ggf. einen Ausschnitt der Textdatei.

    Jahreszeitlich bedingt, habe ich schon eine Vermutung :theke::Glaskugel:

  • Hallo Chaspel.

    Kann man dieses Script irgenwie umschreiben, damit es schneller geht?

    Ich bin mir nicht sicher, was du erwartest. Am besten schreibst du dein Code-Beispiel um, sodass es denen klarer wird, die helfen sollen. ;)

    So hast du z.B. $FileName2, aber ich kann nirgends $FileName1 entdecken. Dann überschreibst du $FileName2 und erhältst $hFilehandle2, das du nirgends benutzt, und $file_name ist in Wirklichkeit ein FileHandle.

    Wie du siehtst, ist es erstmal nötig, Klarheit reinzubringen. Auch solltest du am Ende alle FileHandles mit FileClose() schließen.

    Leider ist die Liste im .txt File grösser als das Array erlaubt.

    Bist du sicher, dass deine Text-Datei 16777216 Zeilen enthält? Das sind fast 17 Millionen. =O

    Edit: Andy Scheinbar haben wir das Gleiche gedacht, nur warst du 2 Minuten früher. 8o

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Unabhängig davon ob du alle Zeilen in einem Array benötigst oder die Zeilen gleich in der Schleife behandeln kannst ist der Grund für das langsame Skript dass du bei filereadline den Zeilenparameter verwendest. Dabei wird bei jedem einzelnen Aufruf die Datei von Anfang an durchlaufen und die Anzahl der Zeilen gezählt bis die gewünschte Zeile erreicht ist. Jedes Mal...

    Daher Hilfe zu filereadline lesen. Dort steht wie man es richtig macht: Datei mit fileopen öffnen und dann filereadline OHNE Zeilenparameter aufrufen. Dann wird nämlich immer die jeweils nächste Zeile ausgelesen anstatt von Anfang an durchlaufen.

  • Ahh, danke euch!!!

    So ist doch schon viel besser.

    Nochmals danke an alle.

    Einmal editiert, zuletzt von Chaspel (31. Dezember 2020 um 14:14)

  • Wie du siehtst, ist es erstmal nötig, Klarheit reinzubringen. Auch solltest du am Ende alle FileHandles mit FileClose() schließen.

    Sehr nett formuliert... die Zeile hast du wohl übersehen?

    $hFilehandle2 = FileOpen($sFileName2, $FO_READ + $FO_APPEND)

    $FO_READ ist 0 und ergibt in Kombination mit $FO_APPEND = $FO_APPEND... also entweder $FO_READ, oder $FO_APPEND.

    Zudem funktioniert FileReadLine eh nur mit $FO_READ (Lesemodus)... nicht aber mit $FO_APPEND oder $FO_OVERWRITE (Schreibmodus)!

    Einmal editiert, zuletzt von Bitnugger (31. Dezember 2020 um 14:05)

  • Zitat von Professor Bernd

    Wie du siehtst, ist es erstmal nötig, Klarheit reinzubringen. Auch solltest du am Ende alle FileHandles mit FileClose() schließen.

    Sehr nett formuliert...

    Vielen Dank! 8o

    die Zeile hast du wohl übersehen?

    Nein! Ich baue eigentlich ständig ein paar kleine Schriebfleher ein, nur um dich zu testen! :P

    $FO_READ ist 0 und ergibt in Kombination mit $FO_APPEND = $FO_APPEND... also entweder $FO_READ, oder $FO_APPEND, oder $FO_OVERWRITE... die Flags schließen sich also gegenseitig aus.

    Bist du sicher? :/

    In der AutoIt Hilfe zu FileOpen() in Beispiel 2, Zeilen 11 und 12:

    ; Öffnet eine Datei für den Lese/Schreib-Zugriff.

    Local $hFileOpen = FileOpen($sFilePath, $FO_READ + $FO_OVERWRITE)

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • So ist doch schon viel besser.

    Das "viel" lassen wir mal weg... 8o

    So ist besser:

  • Bist du sicher?

    Ja... habe die Zeile ein wenig gekürzt, aber dennoch sollte klar sein, dass $FO_READ in Kombination mit $FO_APPEND oder $FO_OVERWRITE keinen Sinn macht... weil $FO_READ ja 0 ist!

    Soeben getestet - mit $FO_APPEND ($FO_READ + $FO_APPEND = $FO_APPEND) funktioniert FileReadLine nur in Kombination mit FileSetPos!

    3 Mal editiert, zuletzt von Bitnugger (31. Dezember 2020 um 14:57)

  • $FO_READ ist 0 und ergibt in Kombination mit $FO_APPEND = $FO_APPEND... also entweder $FO_READ, oder $FO_APPEND, oder $FO_OVERWRITE... die Flags schließen sich also gegenseitig aus.

    Bist du sicher?

    Ja...

    Soeben getestet - mit $FO_APPEND ($FO_READ + $FO_APPEND = $FO_APPEND) funktioniert FileReadLine nur in Kombination mit FileSetPos!

    Das war wohl falsch, denn die Flags schließen sich NICHT gegenseitig aus!

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Je mehr ich darüber nachdenke, desto unklarer wird es. In der Hilfe steht folgende Aussage:

    FileOpen ( "filename" [, mode = 0] )

    mode[optional] Modus in dem die Datei geöffnet werden soll.
    Kann auch eine Kombination aus folgenden sein:
    ...

    Du sagst:

    ... die Flags schließen sich also gegenseitig aus.

    Stimmt... $FO_APPEND + $FO_OVERWRITE macht ja auch Sinn...

    Auch wenn es nicht erkennbar ist, vermute ich, dass es sarkastisch gemeint war. Falls dem so ist, stimme ich zu, dass eine Kombination der beiden Werte KEINEN Sinn machen. Auch von den anderen Werten widersprechen sich einige, z.B. die Zeichenkodierungen.

    Also, der langen Rede kurzer Sinn, heruntergebrochen auf eine einfache Frage: Ist die oben genannte Aussage in der Hilfe falsch?

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Also, der langen Rede kurzer Sinn, heruntergebrochen auf eine einfache Frage: Ist die oben genannte Aussage in der Hilfe falsch?

    Falsch ist sie nicht... kombinieren kannst du die Flags beliebig... macht nur in einigen Fällen keinen Sinn, wie du selbst nun ja auch erkannt hast... und ja, war sarkastisch gemeint. ;)

    Mit ausschließen meinte ich auf logischer Ebene...

  • Falsch ist sie nicht... kombinieren kannst du die Flags beliebig... macht nur in einigen Fällen keinen Sinn,

    Wow, strebst du eine Kariere als Politiker an? :D

    Ok, wenn ich dazu komme, werde ich es Tweaky und Water melden, dann können die beiden entscheiden. Danke für deine Infos! :thumbup:

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    • Offizieller Beitrag

    Ich denke nicht, dass es notwendig ist in der Hilfe auch noch zu erklären, welche Flags (logischerweise) kombiniert werden können. Es muss doch die Entscheidung des Users vorliegen ob er nur Lesen oder evtl. Daten anhängen möchte. Wenn er nicht weiß, was er will, kann er auch nicht die korrekten Flags wählen. Das ist dann aber nicht der Hilfe geschuldet, sondern dem mangelnden Programmiervermögen des Users. 8o

  • Hier noch ein Bsp. mit MsgBox, wo die Kombination der Flags auch keinen Sinn macht... dass musst du Tweaky und Water dann auch melden. 8o

    Code
    #include <MsgBoxConstants.au3>
    
    Local $iMsgBox = MsgBox($MB_SYSTEMMODAL + $MB_DEFBUTTON1 + $MB_DEFBUTTON2 + $MB_DEFBUTTON3 + $MB_DEFBUTTON4, "Title", "DEFBUTTON = $MB_DEFBUTTON1 + $MB_DEFBUTTON2 + $MB_DEFBUTTON3 + $MB_DEFBUTTON4", 10)
    ConsoleWrite("$iMsgBox --> " & $iMsgBox & @LF) ; 1 wenn Enter gedrückt wird.
  • Wenn er (Anm.: der User) nicht weiß, was er will, kann er auch nicht die korrekten Flags wählen. Das ist dann aber nicht der Hilfe geschuldet, sondern dem mangelnden Programmiervermögen des Users. 8o

    Sehe ich auch so !

    Eine gute Hilfe, und wir sind uns sicher einig, dass die AutoIt-Hilfe besser ist, als viele andere, ist immer von Wert. Trotzdem muss sie nicht zwingend zu einem Instrument des 'Betreuten Denkens' werden 8o.

    Ansonsten : Guten Rutsch in neue Jahr :part:.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Hi,

    btt...:Face:

    Es sollte "schneller" als das vorliegende Script eine Datei mit 16777216 Zeilen (Buchstaben ?!) geöffnet und in ein Array eingelesen werden.

    Über die Sinnhaftigkeit dessen habe ich bisher noch keine Antwort erhalten. Weiterhin bemerkt der TE, dass die Textdatei so groß ist, dass diese nicht in das Größenlimit eines Arrays passt. Antwort(en) bisher dazu...keine:Face:

    Ja , die "Lösung" die Funktion FileReadLine ohne den Zeilenparameter aufzurufen, bringt ja schon mal etwas.:party:

    Die im 2. Post vorgeschlagene Methode per Stringsplit (oder auch ggf. noch schneller Regex) schlägt die FileReadLine()-Funktion trotzdem noch um Längen.:rtfm:

    Hab auf die schnelle nur eine bissl mehr als 15Mio Zeilen große Datei testen können:

    Wenn es nächstens also darum geht, ein Script "schneller" zu machen, dann bitte ich auch um Vorschläge dazu. Und auch um Lösungen, wenn Dateiinhalte so groß sind, dass diese nicht in ein Array "passen" ( Bitnugger ausgenommen, FileSetPos() zeigt in die Richtung:thumbup:)

    Die Diskussion darüber, wie blöde oder clever man sein kann/muss, um eine Hilfedatei (wenn überhaupt) zu lesen und Parameter zu kombinieren, ist definitiv unterhalb unseres Niveaus.<X

  • Ohne konkrete Anwendungsfall kann man eigentlich gar nicht Aussagen dazu treffen welche Methode, welche andere schlägt oder nicht. Die benötigten Kriterien sind schlicht noch nicht klar.

    Zur besseren Einordnung was der eigentliche Vorteil von FileReadLine ist, zitiere mich mal von oben selbst:

    Unabhängig davon ob du alle Zeilen in einem Array benötigst oder die Zeilen gleich in der Schleife behandeln kannst

    Die im 2. Post vorgeschlagene Methode per Stringsplit (oder auch ggf. noch schneller Regex) schlägt die FileReadLine()-Funktion trotzdem noch um Längen. :rtfm:

    Erstens hinkt der Speedvergleich etwas - denn StringSplit haut die Zeilen nur in ein Array - die einzelnen Elemente werden jedoch kein einziges mal angefasst.
    Ein jedoch unwahrscheinliches Szenario ist es hierbei aber dass die Werte nur in ein Array landen sollen ohne jemals weiterverarbeitet zu werden.

    Die wirklich wichtige - jedoch fehlende - Information ist aber: Müssen die einzelnen Zeilen unbedingt in ein Array oder würde es nicht eventuell auch reichen sie einmal durchzuiterieren und einzeln zu behandeln?

    Wissen wir jedoch nicht.

    Wäre dies aber hypothetisch der Fall, dann ist die Array-Variante bei mir ca. 17s (wenn man die Einzelelementbehandlung fairerweise auch mit in die Messung einbezieht) gegen 26s klar schneller. Also ca. ein Faktor von 1:1,5. Aber dies ist ja nur ein Kriterium von vielen möglichen.

    Ein anderes wäre z.B. der RAM-Verbrauch. Da ergibt die FileReadLine-Loop bei mir 6,2mb. Die StringSplit-Variante dagegen stolze 2,3GB. Das wäre dann ein Faktor von 380:1...

    Das Grundproblem ist weiterhin das folgende und vorher macht eine Diskussion über die "bessere" Methode nur bedingt Sinn:

    Zeig mal die Anwendung, für die man diese Konstruktion überhaupt benötigt.

    Btw: Warum eigentlich Fileread + StringSplit? Was spricht denn gegen ein simples FileReadToArray? (Edit: das ist ja noch langsamer - da läuft doch irgendwas schief :/)

    3 Mal editiert, zuletzt von AspirinJunkie (2. Januar 2021 um 13:51)

  • Die wirklich wichtige - jedoch fehlende - Information ist aber: Müssen die einzelnen Zeilen unbedingt in ein Array oder würde es nicht eventuell auch reichen sie einmal durchzuiterieren und einzeln zu behandeln?

    THIS!

    Daher auch mein Hinweis auf das (mittlerweile würde ich meinen Arm drauf verwetten) XY-Problem....

    die einzelnen Elemente werden jedoch kein einziges mal angefasst.

    dazu zitiere ich mich mal selbst:

    Kein Mensch braucht ein Array mit derartig vielen "Zeilen" aus einer Textdatei, die mittels FilereadLine ausgelesen werden müssen!

    Da hätte ich mit einem "Doch! Braucht man...weil..." gerechnet, blieb aber aus den bekannten Gründen aus!

    Das verhält sich ähnlich zu den Fällen, wenn alle "Pixel" eines Bildes in ein AutoIt-Array eingelesen und dann bearbeitet werden sollen. Auch dazu gab es schon endlose Diskussionen...

    Das die zu bearbeitenden Daten schon in einem Format vorliegen, welches mit geeigneten Mitteln direkt zu bearbeiten ist, scheint kaum zu interessieren.

    Textdateien bzw. Texten würde ich in Autoit mit entsprechenden Stringbefehlen/funktionen auf den Pelz rücken. Da nativ in C/C++ compiliert, sind diese unschlagbar schnell.

    Btw. sind diese StringFunktionen so schnell, dass man auch bspw. "Bilder" damit bearbeiten kann. Einem Byte ist es gelinde gesagt völlig egal, welchen Wert es repräsentiert. Und der passenden Bearbeitungs-Funktion günstigstenfalls ebenso.

    Jedenfalls hatte es mich interessiert, welche Anwendung beschleunigt werden sollte. Aber auf diese Antwort werde ich wohl weiter warten müssen...