Freitag, 17. Februar 2012

XML Processing with FastInfoset

Wer schon einmal eine Applikation konstruiert hat, welche grosse Mengen von XML-Daten verarbeitet, ist bestimmt schon an den Punkt gelangt, wo die Dauer der Verarbeitung durch die I/O-Geschwindigkeit dominiert wurde.

XML als Format ist oft eine sehr gute Wahl. Die ganze Welt von soliden Tools zur Verarbeitung von XML-Daten erleichtern den Umgang mit den Daten enorm. Ich möchte diese Tools nicht missen. Trotzdem wäre es schön, die Geschwindigkeit der Verarbeitung steigern zu können.
Es gibt mehrere Ansätze dazu.

Komprimieren der XML-Daten vor und nach der Verarbeitung
Der oft gewählte einfache Ansatz ist, die XML-Daten beispielsweise mit GZip zu komprimieren. Das verringert zwar den Speicherbedarf, erhöht aber die Verarbeitungsgeschwindigkeit nicht zwingend.

Effizientere Kodierung der Informationen
Fast Infoset ist ein Standard [1] welcher eine binäre Kodierung für XML beschreibt. Der Standard versucht den Speicherplatz zu verkleinern und die Verarbeitungsgeschwindigkeit zu erhöhen.
Der typische Geschwindigkeitszuwachs beträgt etwa Faktor 10 gegenüber Java Xerces [2] und der Speicherplatzbedarf beträgt in etwa 30% Prozent der Originalgrösse. 
Der Grosse Vorteil dieser Enkodierung ist jedoch, dass sich Applikationen mit minimalem Aufwand darauf erweitern lassen. Die Implementierung von Sun bringt bereits Unterstützung für die XML Standards SAX, StAX und DOM mit [3].
Eine Alternative zu dieser Enkodierung ist der W3C-Vorschlag "Efficient XML Interchange" [4].

StAX XMLWriter mit Fast Infoset
StAXDocumentSerializer serializer = new StAXDocumentSerializer();
serializer.setEncoding("UTF-8");
serializer.setOutputStream(out);
serializer.writeStartDocument();
serializer.writeStartElement("root");
serializer.writeStartElement("record");
serializer.writeCharacters("abcdef123456");
serializer.writeEndElement("record");
serializer.writeEndElement("root");
serializer.writeEndDocument();

SAX Parser mit Fast Infoset
InputStream in = ...
ContentHandler contentHandler = ...
InputSource = new InputSource(in);
XMLReader reader = new SAXDocumentParser();
reader.setContentHandler(contentHandler);
reader.parse(source);