![]() |
Der schnellste weg Dateien zu parsen?
Huhu!
Jemand von euch ne Idee wie man einen Dateiparser realisiert bzw. welcher der performanteste weg ist? dabei gehts mir grundsätzlich um die zugriffszeiten zur datei - die muss ich irgendwie schneller bekommen. im moment arbeitet mein parser jedes zeichen einzeln ab. ich öffne die ( ~20mb ) datei als TFileStream. macht es sinn die datei erst teilweise in den speicher zu holen, damit der parser ansich schnellere zugriffszeiten bekommen kann? kA jeweils immer 2mb in den arbeitsspeicher saugen und dann abarbeiten bevor man sich die datei weiter reinlutscht? jemand ne idee? gruß reli |
Re: Der schnellste weg Dateien zu parsen?
Ja, macht sogar großen Sinn einen Buffer zu benutzen. Die Größe dieses Buffers sollte ca. 8Kb groß sein. Und das Füllen des Buffers aus dem Stream sollte OHNE aufrufe von Stream.Seek(), Stream.Position und Stream.Size auskommen, da exakt diese Funktionen weitaus langsammer sind als Stream.Read() !
Die Schleife könnte so aussehen:
Delphi-Quellcode:
Das vermeidet jeden Aufruf von .Size, .Position usw. und lässt das API quasi linear und sequientiell einfach die Dateo in den Speicher laden. Mit eine Loop wie
repeat
BytesRead := Stream.Read(Buffer, SizeOf(Buffer)); if BytesRead = 0 then Beak; until False;
Delphi-Quellcode:
Würde das API den Dateizeiger bei Stream.Position zur aktuellen Leseposition bewegen, danach gleich ans Ende der der Datei im Stream.Size zu ermitteln und dann bei Stream.Read() wieder zur aktuellen Position. Im ungünstigen Falle also 3 Seek Aufrufe.
while Stream.Position < Stream.Size do
Stream.Read(...) Bei meinem ersten Besipeil würde .Seek() garnicht aufgerufen ! Das kann bei vielen Leseoperationen mehr als 300% die Performance reduzieren !! [edit] Vergiß Memory Mapped Files, früher meinte ich auch das diese Technik schneller sein müsste als nativer Dateizugriff, ich musste mich vom Gegenteil überzeugen lassen. [/edit] Gruß Hagen |
Re: Der schnellste weg Dateien zu parsen?
Hi,
ich bin mir nicht ganz sicher, ob die Abbruchbedingung nicht viel mehr
Delphi-Quellcode:
heißen sollte. Immerhin kann es sein, dass die Datei sich nicht in 8 Byte Blöcke zerlegen lässt, dann wird irgendwann weniger gelsen als der Puffer aufnehmen kann. Da hier die Letzten Byte nicht gefüllt werden hätte man an der Stelle falsche Werte, vorallem kann man aber schon hier abbrechen.
if Stream.Read(Buffer, SizeOf(Buffer)) < SizeOf(Buffer) then
begin break; end; Gruß Der Unwissende |
Re: Der schnellste weg Dateien zu parsen?
danke schonmal für die antworten...
also hagen du meinst das hat ansich keinen sinn oder wie kann ich dein edit interpretieren? |
Re: Der schnellste weg Dateien zu parsen?
@Relicted: Ich glaube Hagens Idee basiert darauf, dass du eine Größe nimmst, die nicht im Arbeitsspeicher sondern im Cache Platz findet. Der native Dateizugriff mittels des Streams dürfte eh vom OS und der Implementierung so gut es geht gecached werden (Festplatten-Cache + Arbeitsspeicher + ...). Da bekommst du dann schon ordentlich Performance von der Seite. An sich kannst du eh nicht bestimmen, ob ein Datum von dir im physikalischen oder virtuellen Speicher landet.
|
Re: Der schnellste weg Dateien zu parsen?
also no way das jetzt noch zu beschleunigen ?
|
Re: Der schnellste weg Dateien zu parsen?
Na du kannst noch ermitteln welche Puffergröße ideal ist, so ca. 8 kByte lässt da ja noch Spielraum offen.
Ich denke mal du solltest eher an einer anderen Stelle die nächste Perfomance rausholen. Das Lesen dürfte mit Hagens Weg schon ziemlich optimal sein. |
Re: Der schnellste weg Dateien zu parsen?
Also es ist schon möglich festzulegen, daß bestellter Speicher ausschließlich im RAM liegt und nicht ausgelagert wird (in der Pagefile landet), aber mit sowas sollte man vorsichtig sein, da so ja schnell der physische Speicher voll sein kann.
Bei 20 MB wäre es gut möglich, daß Teile davon ausgelagert werden (schau einfach mal in den Taskmanager unter Seitenfehler ... jeder Speicherblock, welcher vom Programm verlangt wird und erst aus der Pagefile rausgeholt werden muß, wird da gezählt). Ansich ist Hagens Vorschlag nicht schlecht, da dort nur geringe Anteile der Datei tatsächlich im Speicher liegen ... halt nur die aktuell Benötigten. 8 KB paßt auch gut zur Festplatte, da dort meißtens (mehrere) ganze Cluster reinpassen, was ebenfalls eine Verbesserung mit sich bringt. Dann würde es sich nicht schlecht machen, wenn du deinen Parser noch optimierst und dort auch mal mehr Bytes zusammen verarbeitest (nicht Byte für Byte einzeln). Ein Umstellen von Stringoperationen auf Intergeroperationen bringt auch noch was. (also statt String und Char lieber Byte, Word und Co.) |
Re: Der schnellste weg Dateien zu parsen?
ja wollte die datei wenn dann eh häppchenweise reinfräsen in den speicher :o)
naja ich glaube nicht dass ich an dem parser ansich rumschreibe :o) der mann der den erstellt hat hat auch ahnung von dem was er tut und ich werde mir sicher jetzt nicht 350 dateien zur brust nehmen und darin rumpfuschen :-p versuche halt nur gerade auf biegen und brechen nen paar sekunden in der parse-zeit rauszuholen |
Re: Der schnellste weg Dateien zu parsen?
Zitat:
1.) Puffergröße auf ca. 8Kb, nicht zu klein wie 1Kb und auf keinen Fall größer als 16Kb. Das hat aber was mit dem Caching, der durschnittlichen Dateigröße die man laden möchte und dem Betriebsystem zu tuen. Besnders letzters ist wichtig da es eben von System zu System unterschiedliche Cachegröße/Methoden gibt und 8Kb ist ein Erfahrungswert der im allgemeinen auf allen OS Versionen gute Ergebnisse bringt. Frage mich nicht woher ich das weis ich weis es einfach weil ich schon oft solche Laderoutinen benötgt habe. Ist also ein Erfahrungs-Bauch-Gefühl-Wert ;) 2.) alle Aufrufe die den Dateizeiger verändern, ausser natürlich .Read(), vermeiden. Das kostet die meiste Zeit und kann die Peformance drastisch reduzieren. 3.) deinen Source deines Parsers hast du noch nicht gezeigt, da steckt wohl das meiste Potential drinnen. Versuche mal einfach meine 1. Loop OHNE Parser laufen zu lassen und teste die Geschwindigkeit. Es dürfte beim 1. Aufruf der gleichen Datei wesentöich länger dauern als beim 2. usw Aufruf. 4.) Natürlich gehts nch schneller !! Viel viel schneller !! Kaufe dir eine PCI Karte die zb. 2 bis 4 FPGA Bausteine drauf hat. Dies steckste in deinen Rechner. Programmierst diese Hardware per VHDL damit sie per UltraDMA Mode 6 oder SATA direkt neben der CPU auf deine Festplatte zugreifen kann. Klar das deine FPGA Bausteine auch die FAT/NTFS lesen könen müssen. Das diese FPGA echte programmierbare Hadrware ist und mit bis zu 500Mhz getaktet werden können und zudem noch mit weit mehr als 128 Bit Datenbreite arbeiten können und eine SATA Festplatte bis zu 10GByte an Daten pro Sekunde schaufeln kann, heist dies das du damit theoretisch deine 20Mb Datei in wenigen Millisekunden gepasrst hast. Naja an dann läuft das ding ja auch noch parallel zur CPU ! Also schneller gehts garantiert aber ob du dazu in der Lage bist sowas zu bauen sei angezweifelt. @Unwissender: Die Abbruchbedingung ist schon korrekt so. 1 Loop vor dem Abruch wird .Read () mit 1/SizeOf(Buffer) Wahrscheinlichkeit exakt SizeOf(Buffer) Bytes lesen, aber meistens eben weniger. Der Parser wertet nun immer nur BytesRead Bytes in diesem Buffer aus. In der Letzten Loop haben wir alle Daten gelesen und .Read() wird demzufolge 0 zurück geben müssen. Man hätte auch im until eine Abbruchbedingung wie ByteRead < SoizeOf(Bufer) benutzen können, das könnte aber Nachteile haben. Denn wenn wir die Datei readonly und shared geöffnet haben und ein zweiter Prozess kontinuierich Daten anhängt dann ist es wahrscheinlich das .Read() mehrmals weniger Bytes ausliest aber denoch beim nchsten Read eben wieder neue Daten vorfinden wird. Ergo: logisch gesehen solle die Loop exakt so aussehen wie ich es oben gezeigt habe. Da fällt mir noch eine weitere Methode zur Beschleunigung ein. Öffne die Datei ReadOnly und Exklusiv, dann werden gute OS'e diese Datei schneller nachladen können. Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz