Seite 2 von 3
Verfasst: 03.11.2004 09:29
von Kiffi
> Ich glaube, gerade auf solche Dinge von "3.-Anbietern" wollte er
> Verzichten. So hab ich das aus seinem ersten Beitrag
> herausgelesen.
oha! Habe ich überlesen, Sorry!
Grüße ... Kiffi
Re: Performance beim Lesen von Dateien
Verfasst: 03.11.2004 10:46
von Marc
Erst mal besten Dank an alle für die schnelle Hilfe!
So wie es aussieht, sollte ich mich dann entweder auf den Ansatz von Sunny mit dem Buffer stürzen oder eben doch die Library von Rings benutzen
Jedenfalls sind die mit der Buffer-Methode erreichbaren Zeiten schon mal deutlich angenehmer als die Technik des Zeilenweisen Einlesens *schnarch*
Danilo hat geschrieben:Das Problem ist schon seit Jahren bekannt und Fred weiß auch wie man es besser machen kann. Scheint ihn allerdings nicht
zu interessieren, da es die FastFile schon gibt.
Schade... ich mein, es ist ja klasse, daß es diese Libraries gibt, aber ich es gibt mir immer so ein warmes, beruhigendes Gefühl wenn ich direkt beim ersten Versuch, mal was einigermassen Zeitkritisches zu schreiben, direkt feststelle: "Ja, kann man machen aber nich mit den Defaultbefehlen".
cu
Marc
Re: Performance beim Lesen von Dateien
Verfasst: 03.11.2004 11:30
von Danilo
Marc hat geschrieben:...wenn ich direkt beim ersten Versuch, mal was einigermassen
Zeitkritisches zu schreiben, direkt feststelle: "Ja, kann man
machen aber nich mit den Defaultbefehlen".

Willkommen...

Verfasst: 03.11.2004 16:31
von Andre
@Marc: kann aus eigener Erfahrung die FastFile-Libs von Rings nur empfehlen. Diese zu verwenden, lohnt auf jeden Fall und die notwendigen Code-Änderungen sind minimal wenn nicht sogar einfacher zu handhaben.
Dein Beispiel umgestrickt sieht wie folgt aus:
Code: Alles auswählen
startzeit = ElapsedMilliseconds()
Lines=FastOpenTextFile("x.txt")
If Lines
For a = 1 To Lines
text$ = FastReadLine(a)
Next
Else
Debug "Fehler beim Datei lesen!"
EndIf
dauer = ElapsedMilliseconds() - startzeit
MessageRequester(Str(dauer), text$)
In der aktuellen FastFile-Lib musst Du jedoch 2 Beschränkungen in Kauf nehmen:
- Bug beim Lesen von Dateien, die nicht CR/LF am Zeilenende haben
- Beschränkung auf eine gleichzeitig zu öffnende Datei
Aber Rings arbeitet an neuen Versionen seiner Libs...

Verfasst: 03.11.2004 16:49
von NicTheQuick
Die FastFile-Lib von Rings macht nichts anderes als die Datei in großen Blöcken oder sogar komplett in den RAM zu laden und dann mit direkten Speicherzugriffen zu zerlegen und auszugeben.
Also was Sunny da für eine bestimmte Datei programmiert hat, hat Rings bereits in seiner Library für Textdateien oder Binaries gemacht.
Die Defaut-Datei-Befehle arbeiten also nicht nach diesem Prinzip und lesen nur soviel aus, wie du wirklich brauchst, dann darf vllt. mal ein anderes Programm wo anders auf die Festplatte zugreifen, dann kommt dein nächster Befehl und liest den nächsten Teil deiner Textdatei aus. Das zwischendrin war schon Zeitverschwendung und summiert sich bei großen Dateien eben so auf.
Verfasst: 03.11.2004 17:24
von Ynnus
Und nicht optimiert auf die eine Textdatei, die ich schnell zum Testen erstellt habe. Sowas machen nur Grafikkarten-Hersteller.
Naja, was heißt zugeschnitten auf deine Datei. Sicher, mein erstes Beispiel mit 17 Byte war auf deine Textdatei angelegt, weil ich die gerade da hatte. Allerdings könntest du das auch mit größerem Buffer leicht auf andere Texte beziehen. Mein 2tes Beispiel ließt die ganze Datei von 18 MB ein (ich hab deinen Code so angeändet, dass ich im Endeffekt die Textdatei OHNE Zeilenumbruch hatte) ohne Zeilenbrüche und ist somit nicht nur auf 16 Zeichen pro Zeile Zugeschnitten.
Und außerdem, ReadData ist doch ein Standardbefehl für Dateien, wo ist das Problem?

Das Einlesen direkt in Strings mag recht langsam sein, aber Read-/WriteData ist ebenfalls direkt ein PB-Befehl und deutlich schneller. Und wenn ich richtig informiert bin (hab ich irgendwo mal aufgeschnappt), wird in C++ sowieso alles Stringtechnische per Pointer geregelt, also auch mit Speicherbereichen und nicht simpel und einfach "String = ReadString()", was recht komfortabel ist (leider auch langsam, aber man muss ja nicht ReadString bei großen Datenmengen nehmen).
Vielleicht könnte man den Code so umschreiben, dass er immer Blöcke von 512 KB einließt und diese nach Zeilenumbruch-Zeichen untersucht. Dann kann man diese ja in Strings einteilen. Aber, selbst beim Zeilenweise Auslesen muss man die Zeilen ja irgendwo speichern und zum Ende der Textdatei hat man dann auch etliche Stings mit 18 MB insgesamt im Speicher. Wieso dann nicht direkt und schnell die vollen 18 MB einladen und dann in die Zeilen einteilen?
Verfasst: 03.11.2004 18:15
von Lars
NicTheQuick hat geschrieben:Die FastFile-Lib von Rings macht nichts anderes als die Datei in großen Blöcken oder sogar komplett in den RAM zu laden und dann mit direkten Speicherzugriffen zu zerlegen und auszugeben.
Das stimmt so nicht. So weit ich weiß, tut sie auch das, aber noch etwas
mehr, indem sie spezielle API Befehle verwendet, für genaue Infos fragst
du aber wohl am besten Rings

Verfasst: 03.11.2004 18:28
von NicTheQuick
@Lars: Ich weiß, dass Rings noch etwas mehr macht, allerdings habe ich keine Ahnung was das genau ist und habe es deswegen auch nicht schreiben können. Wie auch immer...

Verfasst: 03.11.2004 20:36
von Marc
@Andre: vielen Dank, super Service
Das sieht einfacher aus, als ich dachte, feine Sache... dann werd ich mal weiter basteln.
Ich hoffe mal, da kommt nich noch so eine Bremse

Verfasst: 03.11.2004 21:47
von Max.
Sunny hat geschrieben:Und nicht optimiert auf die eine Textdatei, die ich schnell zum Testen erstellt habe. Sowas machen nur Grafikkarten-Hersteller.
Naja, was heißt zugeschnitten auf deine Datei. Sicher, mein erstes Beispiel mit 17 Byte war auf deine Textdatei angelegt, weil ich die gerade da hatte. Allerdings könntest du das auch mit größerem Buffer leicht auf andere Texte beziehen. [...]
Natürlich geht das. Aber wie Du sagst, nur um ReadString zu emulieren muss man einiges beachten, grob
1. Buffer anlegen
2. Buffer füllen
3. Nach erstem Vorkommen von Zeilenumbruch suchen
4. Teildaten als String zurückgeben
5. Check ob Buffer durchsucht, ggf. neuen Buffer einlesen und zu Rest des alten Buffers kopieren
6. Check, ob FileEnde erreicht, ohne dass die Datei mit Zeilenumbruch endet
etc. pp.
Dann noch eine "if OS = Linux" Behandlung, da Zeilenumbrüche dort ja anders sind (keine Ahnung von MacOS). Und das noch bei vernünftigem RA(M)-Speicherbedarf.
Wie gesagt, das nur um ein simples ReadString zu emulieren. Wäre interessant, btw. wie da die Geschwindigkeit sich im Vergleich zu anderen Compilern verhält.
Ne, irgendwo erwarte ich tatsächlich von einer Programmiersprache die mit "handoptimierter Maschinensprache" o.ä. wirbt a bisserl mehr.
BTW, ich dachte mein Autobeispiel wäre anschaulich genug.
