Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 05.06.10 14:58 
Ich habe eine Datei, die ich zum Teil in kleinen Blöcken lesen muss, deren Größe nicht im vonrherein feststeht (dynamische Teile anhand der Struktur)
Jetzt jedesmal nen 4 Byte wert zu lesen und dann den nächsten ist aber tod für die performance. Gibt es eine Komponente wie TMemoryStream, die als eine art Cache wirkt? Ein reiner TMemoryStream möchte ich aufgrund der Dateigrößen (möglicherweise >2GB) nicht verwenden
Sprich, dass er immer einen großen Block aus der Datei lädt, von dort aus weiterliest, bis der zu ende ist/wäre (Grenzüberschreitung) und dann den nächsten holt? Möglichst absolut transparent. Da die Idee simpel klingt, nehme ich an, dass es das schon gibt, aber hab nix gefunden.
Wichtig wäre auch noch ein Random access (per filepointer o.ä. identische position die gelesen und gesetzt werden kann)

Das gleiche brauche ich auch fürs schreiben.

Wo gibt es sowas und wie verwende ich es?


Zuletzt bearbeitet von Flamefire am Do 17.06.10 17:36, insgesamt 1-mal bearbeitet
Tryer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 226
Erhaltene Danke: 7



BeitragVerfasst: Sa 05.06.10 16:45 
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 05.06.10 18:43 
Alternativ kannst Du Dir auch einen TFilestream-Wrapper auf Basis von Memory Mapped Files bauen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: So 06.06.10 02:30 
ich würde hier gerne was fertiges verwenden. Wie gesagt: Der Ansatz ist so allgemein, dass ich bestimmt nicht der 1. mit dem problem bin. Und wiederverwendung ist auch ein wichtiges Entwicklungskriterium ;-) (SWT lässt grüßen)
gphugefile sieht erstmal gut aus.
Wenn es noch weiteres gibt oder jmd davon nachteile kennt, immer her damit.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 06.06.10 02:36 
k, dann dürfte die unter www.delphi-forum.de/viewtopic.php?t=99920 verlinkte Unit eigentlich ganz gut passen ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: So 06.06.10 22:15 
ohje. man sollte die threads wirklich zusammenführen.
Problem: veränderbare Dateigröße. Geht mit MMF nicht, oder?
Vl doch einen kleine Wrapper machen. GPHugeFile scheint mir Overkill zu sein
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 22:39 
Ok, da das Thema eher hierhin passt als in den anderen Thread, bleiben wir am besten ab jetzt hier. :D
Hier die Antwort aus dem anderen Thread, ich verweise dort stattdessen einmal hierher.
user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Es dürfte doch reichen, in den Speicher zu schreiben von dem auch gelesen wird, oder? Wie sieht es da mit der Größe aus? Bei MMF müsste doch die Größe schon vorher feststehen, was sie für mich ungeeignet macht.
Du greifst via MMF ja auch nur auf ein Dateihandle zu. Und dessen Größe kannst du natürlich auch verändern.

Damit der Zugriff aber schnell erfolgt, würde ich schon dazu raten die Größe nicht ständig zu ändern, sondern vorausschauend. Und dann kannst du auch mit MMFs beim Schreiben arbeiten. Denn wenn du für jeden 4-Byte Integer z.B. ein neues Mapping erstellen musst, bringen dir MMFs natürlich nix.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: So 06.06.10 23:51 
nja, das Problem ist: Ich schreibe eine dynamische Struktur. Das heißt sogar 4 Byte weise. macht sich also nicht gut.
Weiß nicht, wie gut das gphugefile ist, aber sowas sieht da besser aus. Wenn das ding einen Buffer hat, den er füllt/liest bevor er den als Block in die Datei schreibt/den nächsten Block liest dürfte das besser laufen.
Bei MMFs: Ich könnte die Datei natürlich auch blockweise vergrößern und am Ende dann erst die größe festsetzen, die es wirklich ist, aber da hab ich ein komisches Gefühl dabei. Ein Buffer scheint mir besser.

Was mich an GPHugeFile stört ist der D4 support. Das Ding scheint schon älter zu sein.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 23:59 
Nun ja, es ist ja auch nicht weiter schwer den Zugriff zu buffern. Bei jedem Schreibvorgang wird einfach in einen Speicherbereich geschrieben bis eine bestimmte Größe erreicht ist. Erst dann wird in die Datei geschrieben. Ebenso wird der Buffer geflusht, wenn die Position gesetzt wird.

So viel Code ist das gar nicht. Ob das so viel sinnvoller ist, bin ich mir nicht so sicher. Das kommt aber auch auf den Anwendungszweck an. Mit MMFs kannst du zum Beispiel locker in dem ganzen derzeit gemappten Speicherbereich Änderungen vornehmen. Du kannst also die Daten zum Beispiel inplace bereits bearbeiten ohne diese erst aus Variablen ans Ziel zu schreiben. Und dafür hilft z.B. ein Buffer nicht weiter, weil der hauptsächlich sequentielle Schreibvorgänge zusammenfassen kann.

Es kommt wirklich ganz darauf an welche Operationen in welcher Reihenfolge passieren und wie diese ggf. kombiniert werden. ;-)
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mo 07.06.10 00:22 
Es geht um einen Archivierer der mit MultiChunks arbeitet. Sprich mehrere Dateien.
Er liests aus einer Datei die Struktur (ordner, dateien) sequentiell (dateinamen variabel, 0-terminiert)
Die Dateien selbst kommen dann aus Offsets aus anderen Dateien -->Ab bestimmter Position sequentiell.
Es sollte eigendlich nicht vorkommen, dass wie wild rumgesprungen wird.
Beim schreiben genauso. Gelegendlich muss mal eine Position übersprungen werden (bei gelöschten Dateien) aber meist ist es auch sequentiell.

Darum ebn Buffer. Oder?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 07.06.10 00:38 
Ein Vorteil von MMFs ist natürlich, dass das System das Schreiben auf die Festplatte selbst planen kann, entsprechend der gerade genutzten Systemressourcen. Dafür kannst du mit einem eigenen Buffer das selbst steuern.

Wichtig ist auch, dass du nicht ständig abwechselnd von der Platte die zu archivierende Datei liest und dann schreibst. Deshalb bieten sich zumindest zum Lesen der Dateien auf jeden Fall MMFs an, da du dann den Inhalt in einem Rutsch jeweils im RAM hast.
Beim Schreiben sind eigene Buffer zwar umständlicher umzusetzen, dafür aber auch besser selbst zu steuern.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mo 07.06.10 14:45 
warum sollte ich nicht abwechselnd lesen und schreiben?

Wie müsste ich vorgehen, wenn ich eine MMF habe (z.b. mit deiner Unit) und dort etwas anhängen möchte? Sprich z.b. einen 4Byte Integer schreiben und die Datei um z.b. 4kb vergrößern (als Buffer für folgende Schreiboperationen)
Könntest du mir da mit etwas Code aushelfen?

Ansonsten nehme ich vermutlich eher Buffer. Bei denen weiß ich wenigstens, wie die funktionieren ;-)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 07.06.10 23:56 
user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
warum sollte ich nicht abwechselnd lesen und schreiben?
Weil der Schreib-/Lesekopf der Festplatte dadurch ständig zwischen den beiden Positionen wechseln muss. Dadurch sinkt natürlich die Geschwindigkeit deutlich.
Wenn hingegen immer größere Teile sequentiell gelesen und geschrieben werden, erhöht sich die Geschwindigkeit drastisch. Und gerade bei einem Archivierer ist dies ja ein sehr wichtiges Kriterium.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Wie müsste ich vorgehen, wenn ich eine MMF habe (z.b. mit deiner Unit) und dort etwas anhängen möchte? Sprich z.b. einen 4Byte Integer schreiben und die Datei um z.b. 4kb vergrößern (als Buffer für folgende Schreiboperationen)
FileSeek + SetEndOfFile ;-)
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Di 08.06.10 07:24 
Einige Fragen:
Puffert Windows nicht selbst?
Reichen nicht Delphis eigene TReader und TWriter-Klassen?

_________________
Na denn, dann. Bis dann, denn.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 08.06.10 08:04 
user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:
Einige Fragen:
Puffert Windows nicht selbst?

Ja, geht aber abzuschalten, was an einigen Stellen die Performance stark verbessert ;-)

user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:
Reichen nicht Delphis eigene TReader und TWriter-Klassen?

TReader und TWriter sind nur Wrapper um das Lesen von DFM-/Objekt-Datenströme. Datei-IO machen die selber nicht.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 09.06.10 22:17 
Bin gerade dabei auf Basis von jaenickes MMF unit eine TFastFileStream Klasse zu schreiben. Wird von TStream abgeleitet und kann demzufolge auch alles davon.
Werde die dann unter OpenSource posten.

Bis dahin
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 10.06.10 19:30 
Ok hier die erste Variante. Funktioniert soweit super. Im Test eine Geschwindigkeitssteigerung um 500% beim Einlesen eines Archivs.

PS:
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Die 16 ergibt bei 4K-Pages 64KB an Speicher. Das ist für 16 Bit die maximal adressierbare Speichermenge. Unter 32-Bit-Systemen ist das aber witziger Weise ein extrem guter Kompromiss zum Lesen von Datenblöcken, weil für die meisten Medien (Festplatten, Netzwerk, ...) 64K-Blöcke als obere Grenze recht effizient geholt werden können, ohne zu große Latenzen zu erzeugen.

Die 224 vs. 256 dürfte mit der Vermeidung von zu großen Speicherblöcken auf dem Heap zu tun haben, da dieser für kleine Blöcke optimiert ist. Da bin ich mir aber nicht ganz sicher.


Habe was festgestellt: AllocationGrannularity gibt bereits 64KB zurück.
Wenn ich das mit 16 Multipliziere komme ich auf 1 MB

Was wäre schlau zu wählen?


Zuletzt bearbeitet von Flamefire am Di 15.06.10 17:01, insgesamt 1-mal bearbeitet
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 11.06.10 00:32 
Wenn Du kurze Zugriffszyklen haben willst, dann 64K; wenn Du eher große Blöcke lesen musst, ohne Rücksicht auf die Reaktionszeit der Blocking-Aufrufe, dann eher größer.

Kommt in der Regel auf die Position der Datei an. Im Netzwerk eher kleiner, für lokale Festplatten eher größer.

Bitte schaue mal kurz für negative Positionen in den Original-Filestream rein, wie der die handhabt. Ggf. auf 0 festlegen (Start of File).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Fr 11.06.10 18:03 
Dann lasse ich es so wie es ist. Wird schon passen ;-)
Im Original wird FileSeek aufgerufen. Und das schlägt für negative Positionen einfach fehl. Darum hier nur ein exit.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 17.06.10 15:42 
Anmerkung: Die entsprechende Unit gibt es nun in der OpenSource unit Sparte.
Bugs und Verbesserungen sind gern gesehn ;-)

HIER