AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Der schnellste weg Dateien zu parsen?

Offene Frage von "Relicted"
Ein Thema von Relicted · begonnen am 15. Sep 2006 · letzter Beitrag vom 21. Sep 2006
Antwort Antwort
Seite 1 von 3  1 23      
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#1

Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:05
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
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#2

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:12
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:
repeat
  BytesRead := Stream.Read(Buffer, SizeOf(Buffer));
  if BytesRead = 0 then Beak;
until False;
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

Delphi-Quellcode:
while Stream.Position < Stream.Size do
  Stream.Read(...)
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.
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
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:18
Hi,
ich bin mir nicht ganz sicher, ob die Abbruchbedingung nicht viel mehr
Delphi-Quellcode:
if Stream.Read(Buffer, SizeOf(Buffer)) < SizeOf(Buffer) then
begin
  break;
end;
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.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:21
danke schonmal für die antworten...

also hagen du meinst das hat ansich keinen sinn oder wie kann ich dein edit interpretieren?
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:25
@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.
  Mit Zitat antworten Zitat
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:27
also no way das jetzt noch zu beschleunigen ?
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:30
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#8

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:35
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.)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:38
ja wollte die datei wenn dann eh häppchenweise reinfräsen in den speicher )

naja ich glaube nicht dass ich an dem parser ansich rumschreibe ) 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
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#10

Re: Der schnellste weg Dateien zu parsen?

  Alt 15. Sep 2006, 13:50
Zitat:
also no way das jetzt noch zu beschleunigen ?
Hm, ich habe dir doch oben par Tipps gegeben auf was du achten solltest damit es eben schneller wird.

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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz