Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Schnelle XML Lib für große Dateien gesucht (https://www.delphipraxis.net/132530-schnelle-xml-lib-fuer-grosse-dateien-gesucht.html)

Mithrandir 14. Apr 2009 22:28


Schnelle XML Lib für große Dateien gesucht
 
Hi,

Ich bin im Zuge meines Routenplaners jetzt am Überlegen, ob es nicht sinnvoller wäre, das Rendern der Karte lokal im Programm zu machen, um mehr Kontrolle über die Darstellung zu bekommen.

Die Rohdaten sind in einem XML-ähnlichen Format gespeichert. Der Download für Deutschland fasst "niedliche" 400 MB und ist entpackt gute 4 GB groß.

Aber auch wenn ich nicht selbst das Rendern übernehme, muss ich zum Aufbau einer Web-API für das Programm eine DB mit allen Straßen und Orten Deutschlands und den dazugehörigen Geokoordinaten aufbauen. Testweise habe ich mir die OSM-Datei für Schleswig-Holstein genommen, die entpackt "nur" 128 MB groß ist und ca. 2,5 Mio. Zeilen fasst. Muetze1s XMLLib scheitert leider an der Größe, und himiXML is ja noch nicht feddisch.. :stupid:

Gefallen hat mir OmniXML, was auf meinem Core2Duo-Läppi mit 4GB RAM in gefühlten 2 Minuten mit dem Laden fertig war.


Könnt ihr mir noch andere Libs empfehlen, die vielleicht schneller sind?

Gruß,
Daniel

Muetze1 14. Apr 2009 22:53

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel G
Muetze1s XMLLib scheitert leider an der Größe, ...

Diese benutzt ein DOM Modell und ist kein SAX Parser. Bei deinen Datengrössen musst du diese nicht im Speicher halten, das ist Unsinn. Schon allein aus der Datengrösse her. Genau für solche Fälle sind SAX Parser da und genau diese solltest du dir anschauen. Es geht hier niemals daram alle Daten im Speicher zu halten.

Überhaupt auf die Idee zu kommen, das so zu versuchen, zeigt auf, dass dir diese beiden gegensätzlichen Interfaces zum XML Zugriff nicht geläufig sind. Ich empfehle dir dringendst dich damit zu beschäftigen und dann deine Auswahl/Entscheidung neu zu treffen/überdenken.

Sorry, aber bei solchen Aussagen könnt ich mich immer wieder aufregen. Das erinnert mich gleich an den blöden Kommentar.[/quote]

Nichts persönliches, aber es wird immer gerne gemeckert (hast du nicht getan) und dann ist man schnell der Unfähige, obwohl diejenigen meistens einfach uninformiert sind. Also bitte nicht auf dich beziehen.

Mithrandir 14. Apr 2009 23:07

Re: Schnelle XML Lib für große Dateien gesucht
 
Moin Muetze,

aus deinem leicht gereiztem Kommentar lese ich mal raus, dass ich und der Kollege in deinem Blog nicht die Ersten sind. ;) Das "leider" bezog sich auch eher darauf, dass ich die Lib gerne benutze, da sehr einfach. ;)
Zitat:

Zitat von Muetze1
Überhaupt auf die Idee zu kommen, das so zu versuchen, zeigt auf, dass dir diese beiden gegensätzlichen Interfaces zum XML Zugriff nicht geläufig sind.

Nein, sind sie in der Tat nicht. Wie auch?
Zitat:

Zitat von Muetze1
Ich empfehle dir dringendst dich damit zu beschäftigen und dann deine Auswahl/Entscheidung neu zu treffen/überdenken.

Hast du zufällig n paar Links in deinen Lesezeichen, die mich da informativ weiterbringen, von Wikipedia mal abgesehen? Gerade auch mit Bezug auf Delphi.
Zitat:

Zitat von Muetze1
Also bitte nicht auf dich beziehen.

Ok. ;)


Gruß,
Daniel

Edit: Ich habe eben SAXforPascal entdeckt. Das letzte Downloadpaket ist zwar von 2003, aber ich lasse mich mal überraschen..
Edit2: Nee... Bringt leider nicht das gewünschte Ergebnis, da man soviel anpassen muss. Der Parser bricht bei dem Dokument einfach irgendwann ab... Bin also wieder offen für Vorschläge/andere SAX Implementationen...

Edit3: Soo... Ich habe bei Torry diese Komponente gefunden. Die Webseite gibt es nicht mehr, aber die TALXMLDocument parst die Datei (hat übrigens 14055567 Nodes.. :shock: ) in 28 Sekunden. Das nenne ich mal flott...

Muetze1 15. Apr 2009 06:43

Re: Schnelle XML Lib für große Dateien gesucht
 
Hi!

Zitat:

Zitat von Daniel G
aus deinem leicht gereiztem Kommentar lese ich mal raus, dass ich und der Kollege in deinem Blog nicht die Ersten sind. ;)

Ja, leider. Ich habe schon soviele dumme Diskussionen führen müssen über meine Lib, warum die denn so unfähig mal so schnell 2 GB zu verarbeiten oder was man denn so für einen Scheiss verzapft hat - der geht ja gar nicht bei 500 MB XMLs. Und nach tagelangem e-mail Verkehr darf man sich dann anhören, dass die Lib es einfach trotzdem schaffen muss und SAX & DOM irrelevant sind, da ausreden. Von daher bin ich empfindlich an der Stelle...

Aber ich hatte es auch nicht so verstanden, wie geschrieben: nichts persönliches.

Bei einem DOM Parser wird die XML Datei geparst und jeder Knoten wird entsprechend im Speicher dargestellt und ist somit jederzeit sofort verfügbar. Bei einem SAX Parser wird grundsätzlich nichts im Speicher angelegt sondern er hangelt sich durch die Struktur der XML Datei und ruft immer einen entsprechenden Callback auf für den aktuellen Kontext den er gerade parst (Text, Node, Attribute, etc). Der Callback kann von dem Nutzer des Parsers dann genutzt werden um, wenn Struktur, Position und Name stimmen, die entsprechenden Informationen abzulegen. Dafür kann man dem Sax Parser auch mal sagen: überspringe die aktuelle Subknoten und gehe zum nächsten Knoten auf gleicher Ebene, etc. Auch einen Knoten oder zurück oder direkte Addressierung eines Elementes um von da an zu parsen. Dies ist der richtige Weg bei grossen Datenmengen, da du eh nur einen Teild er Daten aus der großen Menge brauchst. Von daher entweder vor dem rendern der Kartendaten vllt. ein paar Details vorher ermitteln oder alles online ermitteln beim malen. Aber ein kleines Vorcache sollte sich da schon anbieten.

Das SAX Prinzip unterscheidet sich aber halt völlig vom DOM Prinzip, muss es aber auch - sonst würden wir immernoch dabei sein und alle Daten in den Speicher laden.

Und nun zu den Links:

1. DOM Modell: http://www.w3.org/DOM/
2. SAX Modell: http://www.saxproject.org/
3. SAX Implementation für Delphi: http://saxforpascal.sourceforge.net/ (Overview, SAX vs DOM)

Das SAX Projekt ist von 2003 und man müsste nach dem Download erstmal die auf der SF.net Seite angegebenen Bugs fixen, aber es ist eine Möglichkeit. Alle anderen Möglichkeiten wären entsprechende ActiveX Objekte wie z.B. MSXML. Dieser kann beides DOM & SAX und wird ja von CodeGear aufbereitet mitgeliefert.

alzaimar 15. Apr 2009 07:02

Re: Schnelle XML Lib für große Dateien gesucht
 
Darf ich fragen, wieso man die XML-Daten nicht 'einfach' in ein geeignetes Format übersetzt, z.B. in eine Datenbank? Ich weiss zwar nicht en Detail, wie man auf die Daten zugreifen muss, aber imho sollte eine gut geplante Datenbank den Job doch mit links erledigen, oder nicht?

Daniel 15. Apr 2009 07:15

Re: Schnelle XML Lib für große Dateien gesucht
 
Falls Du auf Unicode verzichten kannst, kann ich Dir diese Komponente empfehlen:
http://www.destructor.de/xmlparser/index.htm

Ist ein SAX-Parser und ziemlich flott obendrein.

Mithrandir 15. Apr 2009 08:27

Re: Schnelle XML Lib für große Dateien gesucht
 
Hi ihr,
Zitat:

Zitat von Muetze1
Das SAX Projekt ist von 2003 und man müsste nach dem Download erstmal die auf der SF.net Seite angegebenen Bugs fixen, aber es ist eine Möglichkeit.

Argh, auf die Idee, im Bugtracker zu gucken, bin ich gar nicht gekommen... Danke... :wall: Vielleicht wird das dann ja doch noch was mit SAXforPascal und mir.. :stupid:
Zitat:

Zitat von Muetze1
Alle anderen Möglichkeiten wären entsprechende ActiveX Objekte wie z.B. MSXML. Dieser kann beides DOM & SAX und wird ja von CodeGear aufbereitet mitgeliefert.

Zitat:

Zitat von alzaimar
Darf ich fragen, wieso man die XML-Daten nicht 'einfach' in ein geeignetes Format übersetzt, z.B. in eine Datenbank? Ich weiss zwar nicht en Detail, wie man auf die Daten zugreifen muss, aber imho sollte eine gut geplante Datenbank den Job doch mit links erledigen, oder nicht?

Darfst du. ;) Passiert auch, das habe ich im Eingangspost nicht erwähnt: Es geht mir primär eigentlich nur darum, einmal diese Datei zu verarbeiten, um dann die darin enthaltenen Daten in eine Datenbank zu verwursten. Deswegen brauche ich auch nicht zwingend so ein XML-Monster. Aber StrPos fand ich eher unelegant. Vielleicht könnte man mit RegExen arbeiten... :gruebel:
Zitat:

Zitat von Daniel
Falls Du auf Unicode verzichten kannst, kann ich Dir diese Komponente empfehlen:
http://www.destructor.de/xmlparser/index.htm

Ist ein SAX-Parser und ziemlich flott obendrein.

Die Komponente selbst habe ich schon ausprobiert und mir war es irgendwie nicht möglich, eine funktionierende Demo zu erstellen... :gruebel:
Aber da sprichst du einen Punkt an, den ich selbst noch nicht bedacht habe: Unicode-Fähigkeit müsste gegeben sein. Ich geh zwar nicht davon aus, dass jemals ein Asiate das Programm nutzen wird, aber eventuell gibt es ja Leute aus Deutschland, die in Asien eine Rundreise planen (auch wenn ich mich auf die asiatische Karte dafür noch nicht verlassen würde). Da wäre es ungeschickt, wenn man nur Kästchen sehen würde.

alzaimar 15. Apr 2009 18:47

Re: Schnelle XML Lib für große Dateien gesucht
 
Falls sicher ist, das sich das XML-Format nicht ändert, könnte ein handgebissener 'Parser' die richtige Lösung sein. Mit einem optimierten PosEx aus dem FastCode-Projekt hüpfe ich in einem Knoten der Form '<Foo Uninteresting stuff Bar="Wupdi"..' sehr schnell von '<Foo' zu 'Bar="Wupdi"' und habe somit das Wupdi schnell extrahiert. Ich hüpfe also von Knoten zu den Attributen (die stehts in der gleichen Reihenfolge sein müssen) und wieder zum nächsten Knoten und extrahiere die Daten aus einem 50MB Winzling in knapp einer Sekunde. Großartig optimiert ist mein Code nicht, denn mir reicht das.

Mithrandir 15. Apr 2009 18:58

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von alzaimar
Falls sicher ist, das sich das XML-Format nicht ändert, könnte ein handgebissener 'Parser' die richtige Lösung sein.

Zumindest in nächster Zeit nicht, denke ich zumindest. Man will zwar grad die API auf eine neue Version updaten, aber das verzögert sich zum einen gerade etwas und zum anderen betrifft das auch nur die API, nicht die Rohdaten. :o)
Zitat:

Zitat von alzaimar
Mit einem optimierten PosEx aus dem FastCode-Projekt hüpfe ich in einem Knoten der Form '<Foo Uninteresting stuff Bar="Wupdi"..' sehr schnell von '<Foo' zu 'Bar="Wupdi"' und habe somit das Wupdi schnell extrahiert. Ich hüpfe also von Knoten zu den Attributen (die stehts in der gleichen Reihenfolge sein müssen) und wieder zum nächsten Knoten und extrahiere die Daten aus einem 50MB Winzling in knapp einer Sekunde. Großartig optimiert ist mein Code nicht, denn mir reicht das.

Das klingt sehr interessant. Optimieren kann man ja immer noch und von dem FastCode-Projekt habe ich schonmal gehört. Ist denn die Implementierung so trivial, wie es sich anhört?

bigg 15. Apr 2009 20:17

Re: Schnelle XML Lib für große Dateien gesucht
 
Jetzt mal ehrlich, wenn die XML-Datei stolze 4 GB groß ist, dann drückt wohl eher dein verbauter Festwertspeicher auf die Performancebremse. Da kannst du noch so oft vergleichen. Nicht zu vergessen ist die Tatsache, das sich die Datei beim zweiten Vergleich bereits zum Teil noch im Speicher befindet und du mit Sicherheit dein System nicht neugestartet hast. Zweitens haben Alzamir und Muetze1 vollkommen recht. Ein 4 GB XML-File mit einem DOM-Parser in den Speicher laden ist einfach nur hohl. :stupid:
Ein SAX-Parser mit Hibernate plus entsprechender Datenbank sind da wohl die gewünschte Lösung. :angel:

Mithrandir 15. Apr 2009 20:21

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von bigg
Ein 4 GB XML-File mit einem DOM-Parser in den Speicher laden ist einfach nur hohl. :stupid:

Besten Dank, aber so langsam reichts eigentlich mit den Lobhudeleien für mich... :stupid: :mrgreen:
Zitat:

Zitat von bigg
Ein SAX-Parser mit Hibernate plus entsprechender Datenbank sind da wohl die gewünschte Lösung. :angel:

Und alzaimars Vorschlag? :gruebel:

bigg 15. Apr 2009 20:43

Re: Schnelle XML Lib für große Dateien gesucht
 
Alzamir hat seinen Tipp mit der Datenbank doch schon gegeben.
Haste ja am Anfang nicht erwähnt. :zwinker:

Die Jungs vom FastString-Projekt konnten ihre XML-Bestände mit ihren Routinen ordentlich optimieren, aber bei einer in UTF-8 kodierten XML-Datei, wäre ich da etwas vorsichtiger. Wenn man von Standards abweichen möchte, muss man sich nicht wundern (nicht zwingend jetzt aber vielleicht in zwei Jahren), wenn Datenbestände zur Hälfte inkonsistent sind, weil irgendwelche 0815-Parser die Standards nicht einhalten. So ein XML-Parser schreibt sich ja nun auch nicht von heut auf morgen. (siehe Muetze1, Himitsu, MSXML, OmniXML und Co.)

himitsu 15. Apr 2009 20:50

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von bigg
So ein XML-Parser schreibt sich ja nun auch nicht von heut auf morgen. (siehe Muetze1, Himitsu, MSXML, OmniXML und Co.)

joar, sah anfangs auch einfahcer aus :oops:
nja, nun bin ich schon recht weit, da wär's blöd jetzt aufzuhören ... vorallem da ich hier noch ein Projekt hab, welches mal damit arbeiten soll :stupid: (wegen dem hab ich überhaupt erst damit angefangen)

Mithrandir 15. Apr 2009 20:59

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von bigg
Haste ja am Anfang nicht erwähnt. :zwinker:

Nee... :stupid:

Zitat:

Zitat von bigg
So ein XML-Parser schreibt sich ja nun auch nicht von heut auf morgen. (siehe Muetze1, Himitsu, MSXML, OmniXML und Co.)

Wohl wahr. Ich brauche ja nichts großes. Einfach Knoten einlesen und in eine SQL-DB schreiben. Ich habe jetzt die beiden Artikel entdeckt:

Using XML in Delphi application - Part I Teil I ist eigentlich nicht relevant :stupid:
Using XML in Delphi application - Part II

Ich werde mir wohl eine Klasse schreiben, die zum Einen die XML-Datei parst und zum anderen die Daten in eine DB schreibt. Das ist nach dem Thread in meinen Augen die beste Lösung. Zumal man sicher auch schon ein paar Routen vorberechnen müsste. Ob das aber alles für eine lokale DB taugt... Mal sehen..

Pfoto 15. Apr 2009 21:39

Re: Schnelle XML Lib für große Dateien gesucht
 
Hallo Daniel,

ich verwende NativeXML von SimDesign, kostet nicht viel
und soll auch bei riesigen Datenmengen schnell sein.

Hier mal ein Benchmark eines Demo-Projektes:

Zitat:

Creating an XML document with 100000 nodes...
Creation time: 0,297 sec
Storage time (file): 0,297 sec
Storage time (string): 0,109 sec
Storage time (stream): 0,125 sec
File size: 3000060 bytes
Clearing time: 0,032 sec
Loading time (file): 0,890 sec
Loading time (stream): 0,906 sec
Done.

Edit: Centrino Duo / 1.83GHz
http://www.simdesign.nl/xml.html

Gruß
Jürgen

Mithrandir 15. Apr 2009 21:51

Re: Schnelle XML Lib für große Dateien gesucht
 
Hi Pfoto,

Danke für den Hinweise. :thumb:

Allerdings stoßt es mir etwas sauer auf, wenn ich eine kommerzielle Unit in einem GPL-Projekt verwenden sollte. Dennoch danke.. ;)

Mithrandir 16. Apr 2009 00:04

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel
Falls Du auf Unicode verzichten kannst, kann ich Dir diese Komponente empfehlen:
http://www.destructor.de/xmlparser/index.htm

Ist ein SAX-Parser und ziemlich flott obendrein.

Ich hab den Parser nun zum Laufen bekommen. Gefällt mir, rennt durch die 120 MB Datei innerhalb von 17 Sekunden. Allerdings bekomme ich bei der großen 4 GB Datei den E/A-Fehler 998. Vielleicht finde ich noch raus, wie ich das umschiffe... :gruebel: Um den multi-byte Unicode Support kümmere ich mich, sobald es soweit ist. Jetzt möchte ich erstmal einen stabile Basis schaffen...

Ich danke euch für die Hilfe. :thumb:

Muetze1 16. Apr 2009 09:02

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel G
Allerdings bekomme ich bei der großen 4 GB Datei den E/A-Fehler 998.

Bei Dateien/Adressen größer 2 GB die in einer vorzeichenbehafteten Variablen abgelegt werden, ist das Vorzeichen gesetzt. Dadurch können Adress- und Dateioperationen eine falsche Richtung einschlagen. Vielleicht mal in die Richtung schauen.

Mithrandir 16. Apr 2009 09:10

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von Daniel G
Allerdings bekomme ich bei der großen 4 GB Datei den E/A-Fehler 998.

Bei Dateien/Adressen größer 2 GB die in einer vorzeichenbehafteten Variablen abgelegt werden, ist das Vorzeichen gesetzt. Dadurch können Adress- und Dateioperationen eine falsche Richtung einschlagen. Vielleicht mal in die Richtung schauen.

Hi,

Ja, zum Debuggen war mir das gestern zu spät. :) Ich habe mal geguckt, er hängt bei dieser Funktion:

Delphi-Quellcode:
FUNCTION TXmlParser.LoadFromFile (Filename : STRING; FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
          // Loads Document from given file
          // Returns TRUE if successful
VAR
  f          : FILE;
  ReadIn     : INTEGER;
  OldFileMode : INTEGER;
BEGIN
  Result := FALSE;
  Clear;

  // --- Open File
  OldFileMode := SYSTEM.FileMode;
  TRY
    SYSTEM.FileMode := FileMode;
    TRY
      AssignFile (f, Filename);
      Reset (f, 1);
    EXCEPT
      EXIT;
      END;

    TRY
      // --- Allocate Memory
      TRY
        FBufferSize := Filesize (f) + 1;
        GetMem (FBuffer, FBufferSize);
      EXCEPT
        Clear;
        EXIT;
        END;

      // --- Read File
      TRY
        BlockRead (f, FBuffer^, FBufferSize, ReadIn); //<= DORT. Der Wert von FBufferSize ist durch den Integerüberlauf negativ.
        (FBuffer+ReadIn)^ := #0; // NULL termination
      EXCEPT
        Clear;
        EXIT;
        END;
    FINALLY
      CloseFile (f);
      END;

    FSource := Filename;
    Result := TRUE;

  FINALLY
    SYSTEM.FileMode := OldFileMode;
    END;
END;
Ich werde mal gucken, was es für Lösungen zu diesem Problem im Forum gibt, aber ich denke mal, ich bräuchte irgendwie angepasste Funktionen von FileSize und BlockRead, die eben nicht den Integer nutzen, sondern einen größeren Datentyp.


Gruß,
Daniel

Elvis 16. Apr 2009 09:25

Re: Schnelle XML Lib für große Dateien gesucht
 
Was spricht denn gegen den guten alten XmlReader aus dem .Net Framework?
Der lässt ist ebenfalls non-cahing/forward-only und lässt einige SAX Parser weit hinter sich.

Ist auch noch super easy zu nutzen:
Code:
var readerSettings = new XmlReaderSettings
{
    ValidationType = ValidationType.None,
    IgnoreComments = true
};

using (var fs = new FileStream("yourFrigginHugeFile.xml", FileMode.Open, FileAccess.Read))
using (var reader = XmlReader.Create(fs, readerSettings))
{
    while (reader.Read())
    {
        //...
    }
}

Mithrandir 16. Apr 2009 09:51

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Elvis
Was spricht denn gegen den guten alten XmlReader aus dem .Net Framework?

:gruebel:

Eventuell die Angabe der Delphiversion in meinem Profil :stupid:

Zitat:

Turbo Delphi für Win32
Oder kann ich Win32 und .NET mischen? Nee, eigentlich doch nicht.. :gruebel:

TurboMartin 16. Apr 2009 10:52

Re: Schnelle XML Lib für große Dateien gesucht
 
Solltest Du MySQL nutzen, könnte ja auch das hier für dich von interesse sein :stupid:

himitsu 16. Apr 2009 11:06

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel G
Allerdings bekomme ich bei der großen 4 GB Datei den E/A-Fehler 998.

Zitat:

Zitat von Daniel G
Ich habe mal geguckt, er hängt bei dieser Funktion

deswegen solltest du bei nahezu allen XML-Parsern probleme bekommen, da sie oftmals erstmal die gesamte Datei in den RAM laden und darun dann parsen.

Gut, mein Parser läuft nur stückchenweise und läd größere Dateien möglichst nur in 64 KB-Stückchen, aber dennoch landet der XML-Tree danach im RAM, wie bei vielen anderen Parsern.

Bei mir würde da allerdings eine 1 GB-Datei nur maximal + 64 KB (für's Laden) ~1 GB (die Daten) + ein paar Byte je für je 2 Objekte pro Node belegen, wärend es bei anderen dann 1 GB (für's Laden) + ~1 GB (die Daten) + die Verwaltung ... ja und dann kommt noch die fragmentierung des Speichermanagers dazu ....... also bei über weit 1 GB bekommst du so oder so arbe Probleme diese in ein 32-Bit-Delphi-Programm reinzubekommen, wo nur ~2 GB zur Verfügung stehen.

Wenn mein aktuelles XML-Projekt mal steht, ist zwar noch ein weiterter Parser geplant, welcher dann mit größeren Dateien klar kommen sollte, aber von schnell kann dann nicht mehr die Rede sein, da dieser dann einen Großteil der Daten direkt auf der "langsamen" Festplatte lagert, bzw, liegen läßt.

Mithrandir 16. Apr 2009 11:21

Re: Schnelle XML Lib für große Dateien gesucht
 
Irgendwie ist das alles... :kotz:

Ich hab jetzt also im Prinzip zwei Möglichkeiten: Entweder versuche ich der Lib beizubringen, eine Datei stückchenweise einzulesen, das Eingelesene zu verarbeiten und dann den Puffer für das nächste Stück freizugeben, oder ich nutze gleich eine andere Implementation... :?

himitsu 16. Apr 2009 11:36

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel G
Entweder versuche ich der Lib beizubringen, eine Datei stückchenweise einzulesen...

und das ist nicht so einfach ... was denkst du denn, warum ich etwas an der "Leseprozedur" festhänge? :roll:

Muetze1 16. Apr 2009 11:43

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von himitsu
deswegen solltest du bei nahezu allen XML-Parsern probleme bekommen, da sie oftmals erstmal die gesamte Datei in den RAM laden und darun dann parsen.

Oder einfach MMF nutzen, dann wird gemappt (stückchenweise) und nichts explizit in den Speicher gehauen.

Zitat:

Zitat von himitsu
..... also bei über weit 1 GB bekommst du so oder so arbe Probleme diese in ein 32-Bit-Delphi-Programm reinzubekommen, wo nur ~2 GB zur Verfügung stehen.

So lange die Arbeit mit den Zeigern und offsets nicht mit vorzeichenbehafteten Typen von statten geht, kann man leicht mit FastMM und der $SetPEFlags Compilerdirektive die 3,2 GB nutzbar machen. Ich setze es in ein ein paar Projekten ein (auch grosse) und das klappt einwandfrei. Dann hat man nochmal immerhin 1.2 GB weiteren Spielraum.

/EDIT: zu den MMF: Wenn die XML Lib es unterstützt aus einem TStream Nachfahren zu Laden, dann nutze die MMF Filestream Implementation aus meiner XMLLib. Diese implementiert das MMF transparent ohne das der Nutzer des TStream Nachfahren was davon bemerkt.

Daniel 16. Apr 2009 11:45

Re: Schnelle XML Lib für große Dateien gesucht
 
Wie wäre es denn, sog. "Memory Mapped Files" zu verwenden? Aus Sicht Deiner Anwendung läge die gesamte Datei dann im Speicher und Du kannst mit einem Pointer komplett drüberrutschen. Welche Fetzen der Datei dann tatsächlich im Speicher sind und welche nicht, übernimmt dann das OS.

//edit: gnapf ... zu langsam :stupid:

himitsu 16. Apr 2009 11:48

Re: Schnelle XML Lib für große Dateien gesucht
 
Solange aber ein Node nicht in den gemappten Bereich reinpaßt, muß man mehr Seicher nachmappen ... ist alles schon ein klein bissl aufwändiger. (hatte es anfangs auch mal über MMF, aber es dann doch etwas anders gelöst :angel2: )

oder man mappt die gesamte Datei in den RAM, aber daß hat auch wieder einen kleinen Nachteil ... die Datei müßte dann meistens als ein Stück vorliegen und die müssen erstmal zusammenhängend vorliegen und dann wäre ein ganzes Stück vom virtuellen Speicher belegt.

Muetze1 16. Apr 2009 11:53

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von himitsu
..., aber daß hat auch wieder einen kleinen Nachteil ... die Datei müßte dann meistens als ein Stück vorliegen und die müssen erstmal zusammenhängend vorliegen und dann wäre ein ganzes Stück vom virtuellen Speicher belegt.

Was meinst du mit "als ein Stück vorliegen"? Das OS kümmert sich beim anlegen des Mappings darum wo die Datei liegt. Du musst dir keine Sorge darum machen, dass das Dateisystem diese zusammenhängend irgendwo hingeschrieben hat. Das ist nicht deine Aufgabe und geht dich als WinAPI Anwender nichts an. Dies ist keine Voraussetzung zur Nutzung von MMF!

Mithrandir 16. Apr 2009 11:58

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Muetze1
Oder einfach MMF nutzen, dann wird gemappt (stückchenweise) und nichts explizit in den Speicher gehauen.

Hmm, klingt interessant... :gruebel:
Zitat:

Zitat von Muetze1
So lange die Arbeit mit den Zeigern und offsets nicht mit vorzeichenbehafteten Typen von statten geht, kann man leicht mit FastMM und der $SetPEFlags Compilerdirektive die 3,2 GB nutzbar machen. Ich setze es in ein ein paar Projekten ein (auch grosse) und das klappt einwandfrei. Dann hat man nochmal immerhin 1.2 GB weiteren Spielraum.

Und dann kommt einer auf die Idee, das sog. Planet-File einzulesen. Gepackt 5 GB groß, entpackt das 6-fache. Ich hätte vielleicht auch noch erwähnen sollen, dass die Dateien netterweise Zeilenumbrüche besitzen... :stupid:

Damit ihr mal seht, worüber wir eigentlich die ganze Zeit philosophieren:

So sieht eine OSM-Datei aus:

XML-Code:
 
//Header

<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.5" generator="Osmosis 0.29">
<bound box="53.35408,8.05388,55.09603,12.03859" origin="http://www.openstreetmap.org/api/0.5"/>

//Paar tausend Zeilen übersprungen
<node id="13345659" timestamp="2008-12-14T16:57:25Z" user="Gluko" lat="53.9024873" lon="10.777812"/>
<node id="13345660" timestamp="2008-12-14T16:59:07Z" user="Gluko" lat="53.90483" lon="10.779308"/>
<node id="13345661" timestamp="2008-12-14T16:58:56Z" user="Gluko" lat="53.9045348" lon="10.7796025"/>
<node id="13345662" timestamp="2009-01-23T14:08:35Z" user="itschytoo" lat="53.899494" lon="10.7674726"/>
<node id="13345663" timestamp="2009-03-22T10:48:30Z" user="itschytoo" lat="53.8993371" lon="10.7675229"/>
<node id="13345664" timestamp="2009-01-23T14:08:35Z" user="itschytoo" lat="53.8989988" lon="10.7644318"/>
<node id="13345665" timestamp="2009-02-28T14:21:15Z" user="Maarten Deen" lat="53.8985106" lon="10.759474">
  <tag k="barrier" v="toll_booth"/>
  <tag k="name" v="Herrentunnel Lübeck Nord"/>
  <tag k="operator" v="Herrentunnel Lübeck GmbH &amp; Co. KG"/>
</node>
<node id="13345670" timestamp="2009-01-23T14:08:35Z" user="itschytoo" lat="53.8986935" lon="10.7615206"/>
<node id="13345672" timestamp="2009-01-23T14:08:35Z" user="itschytoo" lat="53.8984061" lon="10.7579444"/>
<node id="13345673" timestamp="2009-03-19T14:20:45Z" user="itschytoo" lat="53.8971746" lon="10.7492752"/>
<node id="13345674" timestamp="2009-01-23T14:08:45Z" user="itschytoo" lat="53.8980463" lon="10.7543967"/>
<node id="13345680" timestamp="2009-03-22T10:48:29Z" user="itschytoo" lat="53.8976444" lon="10.7523478"/>
<node id="13345681" timestamp="2009-03-19T14:23:04Z" user="itschytoo" lat="53.8972377" lon="10.7511739"/>
<node id="13345683" timestamp="2009-03-19T14:24:27Z" user="itschytoo" lat="53.8952786" lon="10.7510925"/>
<node id="13345685" timestamp="2008-09-01T07:03:44Z" user="Lübeck" lat="53.8949418" lon="10.7519724">
  <tag k="created_by" v="JOSM"/>
  <tag k="highway" v="traffic_signals"/>
</node>

//Paar tausend Zeilen übersprungen

<way id="27190543" timestamp="2008-09-20T10:34:08Z" user="phobie">
  <nd ref="275411385"/>
  <nd ref="275411386"/>
  <nd ref="274748737"/>
  <tag k="name" v="Lindenweg"/>
  <tag k="highway" v="residential"/>
</way>
<way id="27190544" timestamp="2008-09-20T10:34:09Z" user="phobie">
  <nd ref="274748080"/>
  <nd ref="298365383"/>
  <nd ref="298365384"/>
  <tag k="noexit" v="yes"/>
  <tag k="highway" v="service"/>
</way>

//Wieder ein paar hundertausend Zeilen übersprungen

<relation id="16007" timestamp="2009-04-13T07:20:56Z" user="UncleOwen">
  <member type="way" ref="24737571" role=""/>
  <member type="way" ref="24737575" role=""/>
  <tag k="name" v="Liebermannweg"/>
  <tag k="route" v="road"/>
  <tag k="created_by" v="JOSM"/>
  <tag k="type" v="route"/>
</relation>

<relation id="16008" timestamp="2009-04-13T07:20:56Z" user="UncleOwen">
  <member type="way" ref="21107760" role=""/>
  <member type="way" ref="24737566" role=""/>
  <member type="way" ref="24737581" role=""/>
  <tag k="name" v="Luise-Schröder Ring"/>
  <tag k="route" v="road"/>
  <tag k="created_by" v="JOSM"/>
  <tag k="type" v="route"/>
</relation>

<relation id="16010" timestamp="2009-04-13T07:20:55Z" user="UncleOwen">
  <member type="way" ref="22672888" role=""/>
  <member type="way" ref="24737825" role=""/>
  <member type="way" ref="24737826" role=""/>
  <member type="way" ref="26248001" role=""/>
  <member type="way" ref="28090656" role=""/>
  <member type="way" ref="28090657" role=""/>
  <tag k="name" v="Esinger Weg"/>
  <tag k="route" v="road"/>
  <tag k="created_by" v="JOSM"/>
  <tag k="type" v="route"/>
  <tag k="highway" v="residential"/>
</relation>

//Ende

</osm>

alzaimar 16. Apr 2009 13:49

Re: Schnelle XML Lib für große Dateien gesucht
 
Bastel Dir deinen eigenen 'Extractor' (Parser kann man das dann nicht nennen), der über ein Sliding Window von z.B. 10MB (Hausnummer) über die Datei rudert und deine Daten aufsammelt.

Du hältst also immer 10MB der Datei im Speicher und sprichst diese als langen String an. WEnn Du bei 90% angelangt bist, verschiebst Du die noch nicht untersuchten 10% nach vorne und lädst dahinter die nächsten 90% rein*. Dann geht es quasi von Vorne wieder weiter. So harkst Du dich duch beliebig lange Dateien und bist auch noch schnell dabei.

* Die 10% sind nur ne Hausnummer. Der Gap hängt mit der zu suchenden/parsen Wortgröße zusammen und verhindert, das der erste Teil des zu suchenden Wortes ganz am Ende des Slidingwindows ist und so nicht gefunden werden würde.

Anstatt 10MB könnten 50 oder 100MB vielleicht günstiger sein. Das müsstest Du testen.

Mithrandir 17. Apr 2009 16:24

Re: Schnelle XML Lib für große Dateien gesucht
 
Moin alzaimar,

ja, ich denke, so werde ich das wohl machen. Wäre es eigentlich.. uhm... "unelegant" Delphi-Referenz durchsuchenReadLn zu verwenden und die Datei zeilenweise einzulesen? Zumindest bei der jetzigen API-Version liegen die Dateien immer mit Zeilenumbruch vor. Würde mir wieder ein paar Zeilen Code sparen.. ;)

//Edit: Mit ReadLN verarbeitet er die kleine Datei bei eingeschalteter Optimierung innerhalb von 10 Sekunden, für die große 4 GB Datei benötigt er gute 2 1/2 Minuten. Dann käme noch die Verarbeitung und das Schreiben in die SQL-DB dazu. Ich habs mitm FileStream zuerst versucht, und einem simplen Beispiel. Aber er hat mir nur Exceptions an den Kopf geschmissen, die mir zumindest nichts gesagt haben... :gruebel:

//Edit2: Gäbe es doch einen MySQL-Dump zum Download... :wall:

//Edit3: Ok, ignoriert meinen Geistesblitz mit ReadLN oben. Ich hatte eben die Erleuchtung bezgl. TFileStream. ;)

Muetze1 17. Apr 2009 19:17

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von Daniel G
//Edit3: Ok, ignoriert meinen Geistesblitz mit ReadLN oben. Ich hatte eben die Erleuchtung bezgl. TFileStream. ;)

Da es grundlegend noch immer XML ist, kannst du alles mit TStream Nachfahren machen, da CR und LF völlig unerheblich sind in einer XML Struktur. Diese werden ignoriert (Ausnahme: innerhalb eines CDATA Wertes).

Mithrandir 17. Apr 2009 19:49

Re: Schnelle XML Lib für große Dateien gesucht
 
Ok,

danke für den Hinweis mit dem CDATA. Sollte wohl nie vorkommen, aber man kann ja nie wissen... ;)

himitsu 22. Mai 2009 12:05

Re: Schnelle XML Lib für große Dateien gesucht
 
ich wollte mir mal dieses NativeXML von SimDesign ansehn ... Post #15
nur existiert die verlinkte Seite nicht (Code 404)
und http://www.simdesign.nl bzw. http://simdesign.nl liefern nur leere Seiten

dann hab ich mal 'nen Test gestartet
Delphi-Quellcode:
fill TXMLFile with 4.000.000 nodes, save into and load this from a file
create:0  fill:413022  save:404106  free:3261
EXMLException: EXMLException (TXMLFile.ParsingTree):
invalid name

Error on byte position 655.447 ("<Node6850 name="fcxv")
create:0  load:157  free:0

fill TXMLDocument with 4.000.000 nodes, save into and load this from a file
...
6,9 Minuten um 1,98 GB RAM zu belegen und zum Erstellen von 4 Millionen solcher Knoten:
XML-Code:
<Node123456 name="fcxvysdfgcxvcx" vc1x3y="fcxvysdfgcxvcx>123456gfdxv234rf56dfgcvbf</Node123456>

Aber wurde ja auch schon erwähnt, daß eine DOM-Version für sowas nicht wirklich geeignet ist (obwohl meine Version 2 irgendwann mal wesendlich mehr verkraften wird und dennoch als DOM läuft)

Na gut, dann muß ich jetzt noch den Grund für diese Exception rausfinden und kann dann mal Testen was mein Code in seinem pseudo-SAX-Mode hinbekommt.
Das wird aber geschwindigkeitsmäßig nie an einen guten und reinen SAX-Parser rankommen können.

Zum Testen hab ich mir mal finland.osm (614 MB) geladen
[edit] OK, ich lad mir gleich nochmal 'ne kleinere Testdatei (das obere Beispiel mit 4.000.000 Knoten ergibt nur eine 386 MB-Datei ... da bekomm ich die 614 wohl nicht direkt geladen :nerd: )

Mithrandir 22. Mai 2009 12:10

Re: Schnelle XML Lib für große Dateien gesucht
 
Hi himi, Niedersachsen hat ungefähr 2 Mio. Nodes, noch vielleicht ne Mille anderer Knoten drauf. ;)

himitsu 22. Mai 2009 12:22

Re: Schnelle XML Lib für große Dateien gesucht
 
Blos mal so aus Interesse ... hast du eigentlich mal alles da runtergeladen und entpackt?

Wie groß mag das denn insgesamt sein? :shock:


ja und mal sehn ... Polen ist grad unterwegs (UMTS ist halt nicht unbedingt flott)

TurboMartin 22. Mai 2009 13:16

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von himitsu
XML-Code:
<Node123456 name="fcxvysdfgcxvcx" vc1x3y="fcxvysdfgcxvcx>123456gfdxv234rf56dfgcvbf</Node123456>

Ist das richtig, dass hinter dem letzten Atribut das " fehlt?

himitsu 22. Mai 2009 13:30

Re: Schnelle XML Lib für große Dateien gesucht
 
ist falsch ... war 'nen Kopier-/Schreibfehler ... also das " ist schon da

hatte die Knotten per Hand direkt aus'm Quelltext
Delphi-Quellcode:
For i := 0 to 3999999 do Begin
  Node := XML.RootNode.Nodes.Add('Node' + IntToStr(i));
  Node.Attributes.Add('name', 'fcxvysdfgcxvcx');
  Node.Attributes.Add('vc1x3y', 'fcxvysdfgcxvcx');
  Node.Data := '123456gfdxv234rf56dfgcvbf';
zusammengesetzt, da ich diese 386 MB XML-Datei grad in keinem Texteditor laden konnte, um es zu kopieren :roll:

Mithrandir 22. Mai 2009 14:47

Re: Schnelle XML Lib für große Dateien gesucht
 
Zitat:

Zitat von himitsu
Blos mal so aus Interesse ... hast du eigentlich mal alles da runtergeladen und entpackt?

Naja, das sog. Planet-File ist mit bz2 gepackt ungefähr 6 GB groß, entpackt 5 - 10 mal so groß. Europa ist im Download 1,6 Gigabyte groß, entsprechend auch hier 5-10 mal.

Ja, sind schon ne Menge Rohdaten... ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 Uhr.
Seite 1 von 2  1 2      

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