# Multithreaded SAXParser



## mikachu (13. Okt 2009)

Hallo Community,

bringt es Vorteile, wenn ich einen neuen Parser baue, welcher einen Thread für das Parsen, und ein weiterer Thread für das Verarbeiten habe?
Die ganzen Events werden in einer Queue gespeichert.

Der ProducerThread parst das XML und fügt die Events in die Queue, damit diese der ConsumerThread sich holen kann und an den Handler weiterreichen.

Alles SAXParser-konform!

Es soll also die Arbeit zwischen Parser und Handler-Aufrufer geteilt werden.
Bringt das Vorteile?

MfG mikachu


----------



## André Uhres (14. Okt 2009)

Vorteile hängen imho von den Erwartungen ab. Welche Vorteile erwartest du denn?


----------



## mikachu (14. Okt 2009)

Performance, Zeiteinsparung.

Weil das geparste nicht von dem gleichen Thread verarbeitet werden muss, sodass dieser sich um das reine Parsen kümmern kann.
Der andere Thread hingegen muss nichts parsen, sondern verarbeitet nur das vom anderen Thread geparste.


----------



## newcron (14. Okt 2009)

Wenn du XML per SAX parst, geht der Großteil der Rechenzeit für den Festplattenzugriff drauf, der sehr viel langsamer als die CPU ist. Wenn du mit den geladenen Daten nicht wirklich aufwendige Berechnungen durchführst, kannst du durch das parallelisieren der Berechnung mit großem Glück vielleicht 5-10% der Berechnungszeit sparen. Das bringt also nicht viel außer eine Menge overhead.


----------



## André Uhres (14. Okt 2009)

Ob in einem Fall eine nennenswerte Zeiteinsparung entsteht, kann imho nur der direkte Vergleich zeigen. Sprich: beide Möglichkeiten implementieren, ausprobieren, Zeiten vergleichen


----------



## newcron (14. Okt 2009)

Ich muss zugeben, probiert habe ich es nicht. 
Würde ich aber auch nicht. Eine XML Datei mit SAX zu Parsen dauert nicht lange. Ich habe mal an einer B2B Software (Automobilbranche - Planung von Autoentwicklung) mitgewirkt, deren daten in 30 MB XML Dateien gespeichert wurden (und das Format war nicht übermäßig aufgebläht!). Wir hatten damals auch große Performanceprobleme beim Laden - das dauerte etwa 1-2 Minuten - mit einem SAX Parser. 

Nachdem sich jemand allerdings mal den Code angesehen hatte, stellte er fest, dass ein Großteil der so geladenen Daten per String-concats (also mit dem + Operator) aneinander gehängt wurde. Das waren unserer Schätzung nach über 10.000 solcher Operationen. Nachdem wir die durch einen StringBuffer ersetzt hatten, dauerte das Laden ca. 10 Sekunden. 
Was ich damit sagen will ist: Wenn dein XML Parsing zu lange dauert, stelle erst mal sicher, dass du kein derartiges Performance-Bottleneck hast oder dass die hohe Ladezeit keine anderen Quellen hat (beispielsweise, weil du während dem laden der XML-Datei darin referenzierte Resourcen wie Bilder lädst) Wenn das Laden der XML Daten hingegen nicht langsam ist, lass es bloß so wie es ist. Warum etwas einfaches, dass gut und schnell funktioniert, kompliziert machen? Außerdem ist SAX-Parsing bei komplizierten Formaten auch schon ohne solche Optimierungen unangenehm genug.


----------



## André Uhres (14. Okt 2009)

Ich würde auch nix optimieren, ausser wenn ein relles Performance Problem vorhanden ist.


----------



## mikachu (15. Okt 2009)

Es soll ja auch mehr oder weniger nur ein Test werden, ob es was bringt, wenn man das eben parallel verarbeitet.

Erstmal muss das Konzept stehen, dann kommen die Versuchsreihen zum Laufen, woran sich dann die Evaluierungsphase anschließt.

Aber ich danke euch für die Hinweise und Tipps.

Edit 1:
Das Parsen an sich geht auch schnell, da wir einfachen String-Content in den XML's stehen haben.
Nur eben die Idee mit der Parallelität bezüglich des Parsens und Verarbeitens (aufgrund der Tatsache, dass es ja HT und Mehrkernprozessoren gibt) hat auch hier eingeschlagen und müsste mal getestet werden.


----------



## mikachu (16. Okt 2009)

So, das Konzept steht schon seit 36h jetzt ;-).

Aufgrund der Tatsache, dass dieser neue Parser ja wie ein SAXParser bedient werden soll, muss dieser von SAXParser ableiten.

Hierbei müssen alle protected Operationen implementiert werden. Unter andrem auch die getXMLReader(), welche von der Elternklasse genutzt wird, um ordnungsgemäß auf den Wunsch des parsens reagieren zu können.

Nun hab ich eine anonyme Klasse von XMLReader erstellt, welche wiederum eine parse( InputSource ) definiert.
(Die ganzen internen Sachen wie die Queue für die Events und die Synchronisationsobjekte hab ich mal nicht aufgeführt, um das anstehende Problem nicht zu kaschieren!)

Und genau jetzt stellt sich mir eine Frage:
Wie kann ich diesen Stream parsen, um die geparsten Events in die Queue einzufügen? Muss ich dieses auch mit einem Defaulthander machen, welcher dann bei jeder überschriebenen Operation die gewonnenen Daten in die Queue einfügt?
Das wäre ja dann doppelt gemoppelt, da der andere Thread ja auch wieder dann die Events aus der Queue entnimmt, diese nochmal parst und dann die entsprechende Operation auf dem eigenen Handler auszuführen.

BTW: im Falle von StAX war das einfach, da StAX den pull-Mechanismus einsetzt, um an die Events zu gelangen.
Aber SAX ist ja eine push-API...


----------

