Announcement

Collapse
No announcement yet.

Warum ist das Speichern von XML Dokumenten so langsam?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Warum ist das Speichern von XML Dokumenten so langsam?

    Hallo,

    Umg.: Delphi 6 Ent. UP2

    Ich lese mittels TMemIniFile Daten aus sehr großen INI-Dateien aus und erzeuge daraus durch TXMLDocument XML-Dateien. Das Auslesen verläuft rasend schnell, aber das Erzeugen der XML-Datei dauert unverhältnismäßig langsam.

    Nachdem die Daten ausgelesen sind, verwalte ich sie in eigenen Klassenstrukturen. Jede dieser Klassen verfügt über eine SaveToXML() Methode. Im Kern tut sie folgendes:<PRE><CODE>
    procedure SaveToXML(var XML: String);
    var
    nodeGroup, nodeItems, nodeData: IXMLNode;
    begin
    with MyXMLDocument do begin
    if not Active the Active := True;
    if Assigned(XMLFindNode(...)) then Exit;
    nodeGroup := ChildNodes[...];
    nodeGroup.AddChild(...).Text := ...;
    nodeItems := nodeGroup(AddChild);
    for I := 0 to FList.Count - 1 do begin
    nodeData := nodeItems.AddChild(...);
    FList[I].AnotherObject.SaveToXML(AXML);
    end;
    SaveToXML(AXML);
    end;
    end;</PRE></CODE>

    Wie man sieht, sind die Klassen auch ineinander eingebettet (z.B. die Einträge in FList stellen wiederum Klassen dar).

    Die Funktion XMLFindNode arbeitet nach XPath-Spezifikation und lokalisiert innerhalb einer XML-Datei einen bestimmten Eintrag. Sie sieht wie folgt aus:<PRE><CODE>
    function XMLFindNode(const GroupName, ObjectName, IDName: String; ID: Integer): IXMLDOMNode;
    begin
    // siehe XPath Spezifikation für das Lokalisieren
    Result := ((MyXMLDocument.DOMDocument as IXMLDOMNodeRef).GetXMLDOMNode).selectSingleNode(Fo rmat('/%s/%s/%s[@%s="%d"]',
    ['MyCompanyName', GroupName, ObjectName, IDName, ID]));
    end;</PRE></CODE>

    Das Problem: Hat z.B. obige Klasse 20000 Einträge in ihrer Liste (FList.Count = 20000), so dauert das Speichern ca. 30 Minuten (!). Das komplette Einlesen und Aufbauen dieser Strukturen selbst geschieht in ein paar Sekunden.

    Danke<br>
    Stephan

  • #2
    Hallo Stephan!

    Leider kann ich Dir die Frage auch nicht beantworten, aber genau das gleiche Problem tritt auf, wenn man mit TClientDataSet arbeitet, der offensichtlich intern ebenfalls mit XML hantiert.

    Bei Strukturen, die übersichtlich sind und wenig "Freitext" beinhalten, halte ich inzwischen Lösungen für geeigneter, die per TextFile arbeiten. Dazu bekommt jedes Object die Methode ReadFromString und WritetoString. Der String selbst wird "händisch xmlisiert".

    Die Gefahr dieser Methode liegt natürlich darin, dass Änderungen in XML zu zwangsweisen Source-Änderungen führen, wenn z.B. händisch der XML-Code erzeugt wird, das Einlesen aber über XMLDocument oder TClientDataSet stattfindet.

    Bei Anwendungsdaten, die ausschließlich vom eigenen Programm genutzt werden, kann dieser Aspekt aber in den Hintergrund treten.

    Gruss, b

    Comment


    • #3
      Hallo Bernhard,

      Danke für Deine Antwort.

      Ich habe mittlerweile einige Tests durchgeführt, mit erschreckendem Ergebnis. Bestimmte Datenklassen dürfen nur einmal in die XML Datei geschrieben werden (Stichwort: Vermeidung von Redundanzen). Dafür habe ich zuerst die XPath-Spezifikation zum Auffinden von Knoten verwendet, mit dem Ergebnis, dass es ewig dauert. Mit steigender Knotenanzahl steigt die Komplexität und damit sinkt die Performanz. Daraufhin habe ich die XPath-Routine rausgeworfen und die Suche einem eigens entwickelten Bayer-Baum (eine der effizientesten Strukturen überhaupt) überlassen. Die Suche liegt im Millisekundenbereich, aber das Schreiben in die XML-Datei dauert weiterhin ewig.

      Fazit: Die Verwendung von TXMLDocument für das Erzeugen mittlerer bis größerer XML-Dateien beinhaltet so seine Tücken. Woran's genau liegt, kann ich gegenwärtig noch nicht sagen.

      Stepha

      Comment

      Working...
      X