Autor Beitrag
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18924
Erhaltene Danke: 1673

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 13:09 
Hallo!

Diese Unit stellt eine Klasse zum schnellen zeichenweisen sequentiellen Auslesen von Textdateien bereit. Dabei werden Memory Mapped Files benutzt, so dass der entsprechende Teil der Datei zuerst in den Arbeitsspeicher eingeblendet wird.
Die Buffergröße ist entsprechend der eigenen Anforderungen einstellbar.

Derzeit wird nur das Auslesen von Strings mit einem festlegbaren Delimiterzeichen unterstützt, aber ich werde noch das Auslesen anderer Datentypen usw. implementieren.

Eine Demo ist mit im Download enthalten, dort wird auch auf Wunsch die Geschwindigkeit gemessen. Dabei komme ich hier bei mir auf ca. 84 MiB/s, also schon eine extrem hohe Geschwindigkeit:
MMFReaderSpeedMeasurement

Features:
  • Schnelles Lesen von Strings via ReadLn
  • Festlegen des gewünschten Delimiters
  • Destlegen der Buffergröße zur besseren Anpassung an eigene Daten
  • Delphi 2009 und 2010 Unterstützung inkl. Unicodedateien *neu*

Lizenz:
MPL 1.1 oder GPL 2.0 oder LGPL 2.1

Installation:
Die Unit muss entweder in den Bibliothekspfad aufgenommen oder dem Projekt hinzugefügt werden, damit die Unit über die uses-Klausel eingebunden werden kann. Dann genügt es das Objekt zu erstellen und damit zu arbeiten:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var
  FileReader: TSJMmfFileReader;
begin
  FileReader := TSJMmfFileReader.Create(edtFileName.Text);
  try
    while FileReader.Position < FileReader.Size do
    begin
      FileReader.Readln(CurrentReadString);
      // ...
    end;
  finally
    FileReader.Free;
  end;

Unterstützte Delphiversionen:
Delphi 6, 7, 2006, 2010
(andere nicht getestet, aber es sollte ab Delphi 6 überall gehen)

Unterstützte Windowsversionen:
Windows 2000, XP, Vista und 7

Weitere Planung:
  • Weitere Datentypen hinzufügen
  • Direkter Zugriff auf den Speicherbereich
Bekannte Probleme:
  • keine


Ich habe die Unit auch hier vorgestellt:
http://www.delphipraxis.net/showthread.php?p=1025890#post1025890
http://forum.delphi-treff.de/showthread.php?29055-SJ-MMF-File-Reader-Schneller-Textdatei-Reader&p=210333#post210333 [aktuell offline]

Schönen Gruß,
Sebastian
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von jaenicke am Mi 15.04.20 21:58, insgesamt 6-mal bearbeitet

Für diesen Beitrag haben gedankt: probare
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 78

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 06.06.10 13:15 
Ich habe sie mir auch mal runtergeladen auch wenn ich bisher keine Verwendung habe, hoffe ich lerne was daraus. :-P

Gruß Dude566

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
jaenicke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18924
Erhaltene Danke: 1673

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 14:37 
Dann lade dir mal die neue Version herunter, damit du nix falsches lernst. Ich hatte da leider nen Speicherleck drin, da ich die MMF-Pointer vergessen hatte freizugeben. :oops:
(Dazu kam gerade in der DP der Hinweis.)
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 78

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 06.06.10 14:41 
Gut, mache ich. Habe sowieso erst ab Dienstag Zeit es mir genau anzuschauen.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
jaenicke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18924
Erhaltene Danke: 1673

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 06.06.10 17:39 
So, ich habe mich da nochmal rangesetzt. Es funktionieren jetzt Delphi 6 bis 2010 und Unicodedateien genauso wie Ansidateien. Wobei die Unicodedateien bei Delphi <= 2007 eben so gut es geht auf Ansi gefaltet werden.

Nebenbei:
Entstanden ist das als Nebenprodukt eines schnellen Registryeditors, deshalb weiß ich nicht ob auch andere Unicodedateien usw. korrekt erkannt werden. Die .reg Dateien funktionieren auf jeden Fall.
jaenicke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18924
Erhaltene Danke: 1673

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 03.07.10 12:28 
Ich möchte an der Stelle auch einmal auf eine Umsetzung als Stream von user profile iconFlamefire hinweisen:
www.delphi-forum.de/viewtopic.php?t=100088
Es ist praktisch eine Weiterentwicklung als Nachfahre von TStream und damit universell einsetzbar. Da er dies dort schon umgesetzt hat, spare ich mir den Aufwand, denn etwas ähnliches hatte ich auch im Sinn. :mrgreen:
MAlsleben
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 302

W2k,WinXP
D3 - DXE3 Enterprise
BeitragVerfasst: Mo 05.07.10 13:04 
Hallo Jaenicke,

müsste zur Bearbeitung von Stings oder ASCII-Dateien TStringList nicht die gleiche Geschwindigkeit bringen, da es ja eine Datei komplett in den Arbeitsspeicher packt?

Gruß Micha.

_________________
Viele Wege führen nach Rom.
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 30

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mo 05.07.10 14:22 
nein!
dort hast du auf jeden Fall eine Teil, der die Datei erst mal in den Arbeitsspeicher laden muss.
Und das ist das langsame! Und genau darum gehts bei den Klassen.
jaenicke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18924
Erhaltene Danke: 1673

W10 x64 (Chrome, Edge)
Delphi 10.4 Ent, Oxygene, C# (VS 2019), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 05.07.10 19:01 
user profile iconMAlsleben hat folgendes geschrieben Zum zitierten Posting springen:
da es ja eine Datei komplett in den Arbeitsspeicher packt?
Du hast das entscheidende Stichwort bereits selbst genannt. Überlege einmal was es bedeutet zum Beispiel eine 100 MiB Datei komplett in den RAM zu laden. Und im Vergleich dazu immer nur Blöcke davon.

Was meinst du ist schneller und speichersparender? ;-)

Dazu kommt, dass eine TStringList zuerst die ganze Datei auch noch nach Zeilenumbrüchen in Zeilen trennt.
MAlsleben
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 302

W2k,WinXP
D3 - DXE3 Enterprise
BeitragVerfasst: Di 06.07.10 09:57 
Hallo,

genau um das komplette bearbeiten einer ASCII Datei ging es mir. Speichersparender ist völlig ausser Frage. Ich habe jetzt die Demo von jaenicke mit einer Datei 124 MB groß, ca. 437000 Datensätze, auf meinem 5 Jahren alten Rechner getestet. Dort wird die Anzahl der Datensätze festgestellt und wenn ich mich irre die komplette Datei gelesen. Beim Einlesen und Feststellen der Datensätze mit TStringlist ist die Performance zumindest in dem Fall von TStringlist nicht langsamer.(mit D2007)
Meine Frage hatte den praktischen Hintergrund, das ein Programm von mir komplette ASCII- Dateien inhaltlich ändert bzw. umformatiert und ob durch diese Unit ohne großen Aufwand die Performance sich signifikant steigern lässt. Zumindest beim Laden der Datei scheint das nicht der Fall zu sein.

Gruß Micha.

_________________
Viele Wege führen nach Rom.
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 30

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 06.07.10 21:09 
TStrings verwendet das hier:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TStrings.LoadFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

TFileStream wiederum greift direkt auf die Winapi zu. Da die Datei komplett gelesen wird, lässt sich da an Performance nicht viel rausholen. Was du versuchen kannst, ist TStringlist abzuleiten und die obige Methode zu überschreiben, damit sie TFastFileStream verwendet. Könnte schneller sein.

Aber wie gesagt: Da lässt sich nicht viel rausholen.

124MB sind zwar noch nicht viel, aber so viel freier Speicher muss erst mal am Stück verfügbar sein. Wenn die Dateien größer werden, bekommst du so Probleme...