Entwickler-Ecke

Open Source Projekte - SJ MMF File Reader 0.2 - Schneller Textdatei Reader


jaenicke - So 06.06.10 14:09
Titel: SJ MMF File Reader 0.2 - Schneller Textdatei Reader
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:
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:

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:Bekannte Probleme:

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

Schönen Gruß,
Sebastian


Dude566 - So 06.06.10 14:15

Ich habe sie mir auch mal runtergeladen auch wenn ich bisher keine Verwendung habe, hoffe ich lerne was daraus. :-P

Gruß Dude566


jaenicke - So 06.06.10 15: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 - So 06.06.10 15:41

Gut, mache ich. Habe sowieso erst ab Dienstag Zeit es mir genau anzuschauen.


jaenicke - So 06.06.10 18: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 - Sa 03.07.10 13:28

Ich möchte an der Stelle auch einmal auf eine Umsetzung als Stream von user profile iconFlamefire hinweisen:
http://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 - Mo 05.07.10 14:04

Hallo Jaenicke,

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

Gruß Micha.


Flamefire - Mo 05.07.10 15: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 - Mo 05.07.10 20: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 - Di 06.07.10 10: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.


Flamefire - Di 06.07.10 22:09

TStrings verwendet das hier:

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...