Performance bei NSXML*-Varianten?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Performance bei NSXML*-Varianten?

    Ich schreibe gerade ein kleines CLI-Programm, das größere XML-Dateien parsen muß. In Swift btw. Es geht dabei um die Auswertung eines japanischen Wörterbuchs.

    Qick und dirty parse ich zur Zeit die Daten, also die Wörterbucheinträge und die Daten jeweils innerhalb der Einträge mit xpath-Abfragen, e.g. NSXMLNode.nodesForXPath("./a/b/c"). Besonders praktisch bei speziellen Attributabfragen, zB. NSXMLNode.nodesForXPath("./a/b/c[not(@*)]")

    Gefühlt verbrate ich damit aber viel zuviel Zeit. Das Parsen der Hauptdatei dauert z.Zt. so um die 60~80 Sekunden auf meiner Hardware. Als Alternative könnte ich mir vorstellen, das ganze über den Zugriff auf die jeweiligen child-Elemente zu lösen, also NSXMLNode.children. Sowas in etwa: for node in xmlNode.children ?? [NSXMLNode]() where node.name == "a" { }.

    Im Gegensatz zum xpath-Ansatz müßte ich dafür aber ziemich viel Code schreiben, ohne zu wissen, ob das im Endergebnis überhaupt etwas bringen würde. Ich habe irgendwie keine Lust, mir auf bloße Mutmaßung hinaus, einen Wolf zu schreiben.

    Meine Frage also: Hat hier jemand Erfahrung damit, wie in der Foundation-API der XPath-Ansatz im Verhältnis zu anderen Lösungswegen abschneidet?
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • gritsch schrieb:

    einfach mal die libxml verwenden
    Was meinst Du, wieviel Zeilen C-Code ich schreiben will, um 'einfach mal' zu wissen, ob das überhaupt...?
    Die NSXML*- und CFXML*-Implementierungen basieren letztendlich ja auch auf libxml. Ich will jetzt nicht das Rad neu erfinden, oder restlos den allerletzten Saft der Zitrone auspressen...

    @little_pixel Das Programm _ist_ quasi der Konverter. Es liest einmal die Daten ein, verarbeitet die entsprechend der gegebenen Argumente und spuckt dann wieder was anderes aus....
  • tsunamix schrieb:

    gritsch schrieb:

    einfach mal die libxml verwenden
    Was meinst Du, wieviel Zeilen C-Code ich schreiben will, um 'einfach mal' zu wissen, ob das überhaupt...?Die NSXML*- und CFXML*-Implementierungen basieren letztendlich ja auch auf libxml. Ich will jetzt nicht das Rad neu erfinden, oder restlos den allerletzten Saft der Zitrone auspressen...

    @little_pixel Das Programm _ist_ quasi der Konverter. Es liest einmal die Daten ein, verarbeitet die entsprechend der gegebenen Argumente und spuckt dann wieder was anderes aus....
    Ich weiß ja nicht wie viele du schreiben WILLST, aber mit etwa 20 zeilen sollte man schon sehr viel erreichen. error-handling kannst du ja einbauen nachdem du die geschwindigkeit gemessen hast.
    Mir ist bekannt, dass die drauf aufbauen, schneller wirds daruch aber nicht und weniger overhead gibts auch nicht.
  • XPath-Zugriffe auf einen DOM-Baum sind schon relativ aufwändig. Ob eine andere Lösung eventuell wesentlich performanter ist, hängt zunächst einmal von der XML-Struktur und den Zugriffen ab.

    Häufig bekommt man über einen SAX-Parser und eine problem-optimierte Speicherung (z. B. Dictionaries) schon recht einfach schnellere Zugriffe hin.


    gritsch schrieb:

    ansonsten einfach mal die libxml verwenden. darin gibts ja auch xpaths etc.
    Das dürfte qualitativ kaum einen Unterschied machen. Schließlich basiert die Foundation-XML-Implementierung bereits auf C-Code. Wenn man schon die Geschwindigkeit optimieren will, sollte man als erstes auf XPath verzichten.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:




    gritsch schrieb:

    ansonsten einfach mal die libxml verwenden. darin gibts ja auch xpaths etc.
    Das dürfte qualitativ kaum einen Unterschied machen. Schließlich basiert die Foundation-XML-Implementierung bereits auf C-Code. Wenn man schon die Geschwindigkeit optimieren will, sollte man als erstes auf XPath verzichten.
    Das ist mir klar, aber manchmal wird in den apple-wrappern soviel rumkopiert und overhead produziert dass einem übel werden könnte.
    Wenn er von 60 sekunden spricht dann gehe ich mal von einer xml datei aus die ein paar GB groß ist (und dann spielt memory-management eine große rolle)
  • gritsch schrieb:

    Wenn er von 60 sekunden spricht dann gehe ich mal von einer xml datei aus die ein paar GB groß ist (und dann spielt memory-management eine große rolle)
    Wenn du aus einer großen XML-Datei nur wenig Daten brauchst, kann XPath ja ganz ok sein. Für den wiederholten Zugriff ist es aber einfach zu langsam, gerade bei riesigen Dateien.

    @tsunamix: Eine andere Möglichkeit ist ein Konverter, der das XML in ein günstigeres Format umwandelt. Z. B. Daten erst in JSON konvertieren. JSON lässt sich viel schneller parsen.
    „Meine Komplikation hatte eine Komplikation.“
  • gritsch schrieb:

    Wenn er von 60 sekunden spricht dann gehe ich mal von einer xml datei aus die ein paar GB groß ist (und dann spielt memory-management eine große rolle)

    Öhhh..... *hüst* *räusper*... Die Datei ist eigentlich gerade mal 80 MB oder so groß, ähhh... klein? *rot*.... *schäm*... :)

    Ich will kein großes Versteckspiel spielen. Die Daten, die ich verarbeiten will, sind sowieso alle öffentlich. Ein paar kleinere Dateien, die ich verquirle, werde ich noch klein kriegen. Wirklich Zeit braucht eigentlich nur die Datei dieses Projekts: The JMDict Project.

    Es war meine Vermutung, daß ein SAX-Parser natürlich schneller ist. Der Name fiel mir nicht mehr ein. *nochmal rot* Gibt es in der NSXML*-API einen event driven SAX-Parser-Ansatz?
  • macmoonshine schrieb:

    @tsunamix: Eine andere Möglichkeit ist ein Konverter, der das XML in ein günstigeres Format umwandelt. Z. B. Daten erst in JSON konvertieren. JSON lässt sich viel schneller parsen.
    Mhhh.... Klar... *grübel* hatte @little_pixel ja schon mal eingehend in etwa angestoßen. Für gewisse Aufgaben kann man natürlich eine Konvertierung in ein anderes Format in Betracht ziehen.

    Bleibt noch die Fragestellung: Steht der Codeaufwand von imperformantem Konverter zu performantem Endprodukt in einem akzebtablen Verhältnis?
  • Naja, normalerweise sollte das Parsen einer 80 MB-datei shr viel schneller gehen (weit unter einer sekunde).

    Aber wie gesagt gehe ich davon aus dass apples wrapper extrem viel overhead produzieren (jeden string zb in utf16 konvertieren und im speicher halten).

    Am besten ist du parst das einmal, extrahierst die daten die du brauchst und bringst es in ein für dich passendes format (SQLite, JSON, BSON, abgespecktes XML etc).
    Dann ist ja egal ob das einmalig 5 minuten dauert oder "nur" 5 sekunden.
  • macmoonshine schrieb:

    tsunamix schrieb:

    Gibt es in der NSXML*-API einen event driven SAX-Parser-Ansatz?
    Ja klar: NSXMLParser
    jeeze, f***ing hell.... ja natürtlich!
    Danke!^^

    Muß ich mir unter Tageslicht (z. Zt. Mangelware) noch mal genauer anschauen, wie das dann aussehen könnte. Wie konnte ich das selber übersehen? *rot*
    Das riecht nach einem guten Kompromiß zwischen Codeumfang und Performance...
  • tsunamix schrieb:

    gritsch schrieb:

    Naja, normalerweise sollte das Parsen einer 80 MB-datei shr viel schneller gehen (weit unter einer sekunde).
    Oh je! Da bin ich dann wohl doch sehr weit von entfernt... :(

    Erlaube mir trotzdem bitte die Nachfrage: Kannst Du mir ein Projekt verlinken, das die NSXML*-API benutzt und sowas in der Zeit hinbekommt?
    Ich hab letztens ein XML parsen müssen.
    Unter OS X und Windows.
    XML ca 65 MB groß.
    dekomprimiert (zlib), dom-parser von libxml, paar werte rausgefischt und fertig. Das ganze dauert auf einem normalen desktop PC oder Mac ca 200-500 ms.

    Wie gesagt befürchte ich dass es bei dir viel overhead und vor allem überflüssige convertierungen der UTF8 source geben wird.