@Oscar hast du nen Rechner vom Wetterdienst?
Oder hast du schon eine Testmaschine davon zu Hause?
Acer Predator 21 X
@Oscar hast du nen Rechner vom Wetterdienst?
Oder hast du schon eine Testmaschine davon zu Hause?
Acer Predator 21 X
@Oscar hast du nen Rechner vom Wetterdienst?
Oder hast du schon eine Testmaschine davon zu Hause?
Acer Predator 21 X
Das einlesen bei mir dauert auch nur etwas über 10 Sekunden. Bei dir wirds sicherlich auch nicht merklich länger dauern.
Ich denke mal der TE verschweigt uns irgendwas oder sieht den Wald vor lauter Bäumen nicht.
Die WIN-API-Funktionen sind bei mir Faktor 4 schneller als die AutoIt-Pendants.
Oscars 260MB-Datei wird mit meinem Script in knapp 3 Sekunden eingelesen, mit Oscars AutoItscript dauert es wie gesagt eine Minute! Ich weiß nicht, was da so dermaßen schief läuft...
>Running:(3.3.14.2):C:\Program Files (x86)\AutoIt3\autoit3.exe "D:\Autoitscripte\test33.au3"
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
69516.9044993424
//EDIT, na gut, wenn ich die Tooltip-Zeile auskommentiere, wird die Einlese-Zeit auf 18 Sekunden reduziert. Immer noch 6x langsamer als per Win-API
Deine WinApi-Version liest aber die gesamte Datei komplett in den Buffer.
Das wäre in AutoIt eher vergleichbar mit:
$iTimer = TimerInit()
$sFilename = @ScriptDir & '\!bigdata.txt'
$sData = FileRead($sFilename)
ConsoleWrite(TimerDiff($iTimer) & @CR)
So dauert das bei mir nur ca. 4 sek.
Ursprünglich ging es ja darum, dass nicht genug RAM vorhanden ist (Warum auch immer? Der TO schweigt sich ja aus.), um die Datei komplett in den Speicher zu laden.
Daraufhin dann die Version mit FileReadLine, sodass sich immer nur eine Zeile im Speicher befindet.
Aber das dann so verschiedene Ergebnisse bei dem Test rauskommen hätte ich jetzt auch nicht gedacht.
Hallo alle zusammen! Ich bin es euch wohl noch schuldig zu antworten.
Erst einmal herzlichen Dank für eure zahlreichen Beiträge und eigenständigen Versuche!
Eure Scripts funktionieren bei mir in ähnlichem Tempo, der PC war also nicht der Punkt.
Ich werde mich wohl in die Ecke verziehen und schämen müssen.
Der Flaschenhals und mein großer Fehler war die Verwendung von _ArrayAdd.
In meinem Eröffnungsbeitrag schrieb ich etwas von 5mio Zeilen, drum habt ihr auch 5mio Zeilen verwendet - vollkommen richtig!
Ich habe mein Script jedoch über meine fertige Datei laufen lassen, welche ungefähr 5mio Zeilen hatte. Drum habe ich jede Zeile per FileReadLine eingelesen und dann per _ArrayAdd an meinen (nicht vorher komplett definierten Array) File-Array gehangen. Da ich zwei dieser Dateien gleichzeitig eingelesen habe ist er immer zwischen den Dateien hin und her gesprungen und hat somit 2 _ArrayAdd Befehle pro Zeile durchgeführt.
(Entsprechend ging ich auch beim Buffer vor, der immer "resettet" wurde und dann erneut - sinnloserweise - 1000 Zeilen eingelesen hat.)
Ich habe also versucht mit eurer Hilfe die Symptome zu bekämpfen, ohne das eigentliche Problem anzugehen - welches ich euch aber ja auch verschwiegen habe, da ich es nicht ansatzweise dort vermutete.
Dank euch habe ich also nun ein millionenfach schnelleres Script schreiben können!
Ich bedanke mich also noch mal ganz herzlich bei euch & für eure Geduld mit mir!
Ich habe mir auch mal eine 230MB Datei erstellt... hat auch gute 4 Sec. gebraucht... also fahre ich technisch quasi auf "Halber Fahrt"
Da MorsGER ja seinen Fehler selber gefunden hat, Thema erledigt
@Oscar,
meine Version, die Datei per Win-API einzulesen, hat ja nicht nur den Grund schneller zu sein, sondern verschiedene Blockgrößen für das Lesen einstellen zu können.
Damit ist es möglich, wesentlich größere Dateien (bei Win64 NTFS bspw. 16 Exbibyte (EiB) = 2^60 Byte = 1 152 921 504 606 846 976 Byte) einzulesen!
Per SetFilePointer() kannst du irgendeine Stelle in der Datei "anspringen", und von dort aus eine (vom allozierbaren Speicher abhängige) Größe von Bytes einlesen.
Das Problem stellt sich doch genau wie in diesem Post beschrieben dar....
User will eine Datei "zeilenweise" in ein Array einlesen. So weit, so gut. Mir stellt sich da die Frage der Sinnhaftigkeit dieses Vorhabens, da eine Textdatei bereits ein Array IST! Aber das ist nicht das Problem.
Das Problem, insbesondere bei AutoIt, ist die extrem langsame interne Kopiererei und Anforderung von Speicher intern. Für jede Kopieraktion innerhalb des Speichers wird ca. doppelt so viel Speicher wie nötig angefordert. Wenn man den Dateimanager offen hat und per AutoIt eine ca. 1 Gig große Datei per FileRead() einzulesen versucht, kann man sehen, dass AutoIt irgendwann bei ca. 2.8 Gig "Speicherverbrauch" abstürzt.
Fülle per API-Fileread einen Speicherpuffer (DllStructcreate() ) mit einem Dateiinhalt von 520MB, das dauert selbst auf meinem langsamen Rechner nur ca. 1 Sekunde. Kommt gut hin, meine SSD schafft angeblich 500MB/s aber du weißt ja, der Ingenieur teilt durch 2 und ist auf der sicheren Seite.
Genau so schnell lassen sich die Blöcke von 500MB Größe einer mehreren Gigabytes großen Datei einlesen. DAS geht sehr schnell, "nur" die Weiterverarbeitung ist langsam....insbesondere, wenn man auch noch "langsam" programmiert bzw. "langsame" Funktionen verwendet.
Ein Bekannter sucht aktuell in hunderten von ca. 4Gig großen Videodateien nach irgendwelchen "Markern". Ich habe von Video nicht viel Ahnung, interessiert mich aber auch nicht, hauptsache die Marker werden in den 4 Gig innerhalb von ca. 10-15 Sekunden gefunden/ersetzt.
Auf meinem Rechner die Datei(en) in Blöcken von 500MB Größe einlesen dauert ca. 1 Sekunde, die Suche nach den "Markern" innerhalb dieses Blocks dauert ca. 1 Sekunde, voila...
Ich hätte gerne mit dem unschlagbar schnellen Autoit-StringRegExp() gesucht, leider dauert das oben beschriebene, AutoIt-interne kopieren des Strings aus der DllStruct 5x länger als die eigentliche Suche... So musste ich (leider) auf ASM-SIMD ausweichen (aus Übungszwecken nach einer C-Dll portiert), in Verbindung mit Multithreading für die Suche wird nun eine 4Gig große Datei mit 450MB/s gelesen und durchsucht/ersetzt! Dieses schnelle Lesen ist nur infolge RAID 5 und schnellen Platten möglich, das eigentliche Suchen/Ersetzen wird in der Zeit durchgeführt, in der der nächste Datenblock geladen wird.
"Von Hand" also Videodatei in Editor laden, per Script die Marker setzen und abspeichern dauert lt. seiner Aussage "ewig", also mehrere Minuten.
Wenn man den Dateimanager offen hat und per AutoIt eine ca. 1 Gig große Datei per FileRead() einzulesen versucht, kann man sehen, dass AutoIt irgendwann bei ca. 2.8 Gig "Speicherverbrauch" abstürzt.
Kann es sein das du das bei einer alten Verison getestet hast?
Bei mir kommt AutoIt bei einer 1.2 GB Datei max. auf 1.7GB bis der Verbrauch dann wieder abfällt wenn die Variable nicht mehr genutzt wird.