Java marshaller performance

23,192

Solution 1

Seconding the Use of JibX. Like questzen, I found that JibX was 9 times faster than JAXB in my performance tests.

Also, make sure you have woodstox on the classpath when using JibX. I found woodstox's Stax Implementation is roughly 1050% faster than the Java6 implementation of Stax.

Solution 2

Make sure you create the JaxB context instance only once, creating the context takes some time as it uses reflection to parse the object's annotations.

Note that the JAXBContext is thread safe, but the marshallers\unmarshallers aren't, so you still have to create the marshaller for every thread. However I found that creating the marshallers when you already hold a jaxb context is pretty fast.

Solution 3

Byeond other good suggestions, I suggest there is something wrong with the way you use JAXB -- it is generally reasonably well performing as long as:

  • You use JAXB version 2 (NEVER ever use obsolete JAXB 1 -- that was horribly slow, useless piece of crap); preferably a recent 2.1.x version from http://jaxb.dev.java.net
  • Ensure that you use SAX or Stax source/destination; NEVER use DOM unless you absolute must for interoperability: using DOM will make it 3 - 5x slower, without any benefit (it just doubles object model: POJO -> DOM -> XML; DOM part is completely unnecessary)
  • Ideally use fastest SAX/Stax parser available; Woodstox is faster than Sun's bundled Stax processor (and BEA's ref. impl. is buggy, no faster than Sun's)

If JAXB is still more than 50% slower than manually written variant, I would profile it to see what else is going wrong. It should not work slowly when used properly -- I have measured it, continuously, and found it so fast that hand-writing converters is usually not worth time and effort.

Jibx is a good package too btw, so I have nothing against trying it out. It might still be bit faster than JAXB; just not 5x or 10x, when both are used correctly.

Solution 4

If large XML trees are written, providing a BufferedOutputStream to the javax.xml.bind.Marshaller.marshal(Object jaxbElement, java.io.OutputStream os) method made a big difference in my case:

The time needed to write a 100MB XML file could be reduced from 130 sec to 7 sec.

Solution 5

We have just tracked down a JAXB performance problem related to the default parser configuration used by Xerces. JAXB performance was very slow (30s+) for one data file (<1Mb)

Quoting "How do I change the default parser configuration?" from http://xerces.apache.org/xerces2-j/faq-xni.html

The DOM and SAX parsers decide which parser configuration to use in the following order

  1. The org.apache.xerces.xni.parser.XMLParserConfiguration system property is queried for the class name of the parser configuration.
  2. If a file called xerces.properties exists in the lib subdirectory of the JRE installation and the org.apache.xerces.xni.parser.XMLParserConfiguration property is defined it, then its value will be read from the file.
  3. The org.apache.xerces.xni.parser.XMLParserConfiguration file is requested from the META-INF/services/ directory. This file contains the class name of the parser configuration.
  4. The org.apache.xerces.parsers.XIncludeAwareParserConfiguration is used as the default parser configuration.

Unmarshalling using JAXB results in this algorithm being repeatedly applied. So a huge amount of time can be spent repeatedly scanning the classpath, looking for the configuration file that doesn't exist. The fix is to do option 1, option 2 or option 3 (create the configuration file under META-INF). Anything to prevent the repeated classpath scanning.

Hope this helps someone - it's taken us days to track this down.

Share:
23,192
cbz
Author by

cbz

Updated on July 09, 2022

Comments

  • cbz
    cbz almost 2 years

    I've used JAXB Marshaller as well as my own marshaller for marshalling pure java bean objects into XML. It has been observed that both of them require almost same time to marshal. The performance is not acceptable and needs to be improved. What are possible ways where we can improve performance of marshaller? Like threading?