{"id":1216,"date":"2012-05-24T16:00:00","date_gmt":"2012-05-24T16:00:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/xml-unmarshalling-benchmark-jaxb-vs-stax-vs-woodstox.html"},"modified":"2012-10-22T05:04:17","modified_gmt":"2012-10-22T05:04:17","slug":"xml-unmarshalling-benchmark-jaxb-vs","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html","title":{"rendered":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\"><strong>Introduction<\/strong>  <\/p>\n<p>Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I wanted to solve was how to process large XML files in chunks while at the same time providing upstream\/downstream systems with some data to process. <\/p>\n<p>Of course I&#8217;ve been using JAXB technology for few years now; the main advantage of using JAXB is the quick time-to-market; if one possesses an XML schema, there are tools out there to auto-generate the corresponding Java domain model classes automatically (Eclipse Indigo, Maven jaxb plugins in various sauces, ant tasks, to name a few). The JAXB API then offers a Marshaller and an Unmarshaller to write\/read XML data, mapping the Java domain model. <\/p>\n<p>When thinking of JAXB as solution for my problem I suddendlly realised that JAXB keeps the whole <em>objectification <\/em>of the XML schema in memory, so the obvious question was: &#8220;How would our infrastructure cope with large XML files (e.g. in my case with a number of elements &gt; 100,000) if we were to use JAXB?&#8221;. I could have simply produced a large XML file, then a client for it and find out about memory consumption. <\/p>\n<p>As one probably knows there are mainly two approaches to processing XML data in Java: DOM and SAX. With DOM, the XML document is represented into memory as a tree; DOM is useful if one needs cherry-pick access to the tree nodes or if one needs to write brief XML documents. On the other side of the spectrum there is SAX, an event-driven technology, where the whole document is parsed one XML element at the time, and for each XML significative event,  callbacks are &#8220;pushed&#8221; to a Java client which then deals with them (such as START_DOCUMENT, START_ELEMENT, END_ELEMENT, etc). Since SAX does not bring the whole document into memory but it applies a <em>cursor like<\/em> approach to XML processing it does not consume huge amounts of memory. The drawback with SAX is that it processes the whole document start to finish;  this might not be necessarily what one wants for large XML documents. In my scenario, for instance, I&#8217;d like to be able to pass to downstream systems XML elements as they are available, but at the same time maybe I&#8217;d like to pass only 100 elements at the time, implementing some sort of <em>pagination <\/em>solution. DOM seems too demanding from a memory-consumption point of view, whereas SAX seems to coarse-grained for my needs.  <\/p>\n<p>I remembered reading something about STax, a Java technology which offered a middle ground between the capability to <em>pull XML elements <\/em>(as opposed to pushing XML elements, e.g. SAX) while being RAM-friendly. I then looked into the technology and decided that STax was probably the compromise I was looking for; however I wanted to keep the easy programming model offered by JAXB, so I really needed a combination of the two. While investigating STax, I came across <a href=\"http:\/\/woodstox.codehaus.org\/\" target=\"_blank\" title=\"Woodstox\">Woodstox;<\/a>  this open source project promises to be a faster XML parser than many othrers, so I decided to include it in my benchmark as well.  I now had all elements to create a benchmark to give me memory consumption and processing speed metrics when processing large XML documents.<\/p>\n<p><strong>The benchmark plan<\/strong>  <\/p>\n<p>In order to create a benchmark I needed to do the following:            <\/p>\n<ul>\n<li>Create an XML schema which defined my domain model. This would be the input for JAXB to create the Java domain model<\/li>\n<li>Create three large XML files representing the model, with 10,000 \/ 100,000 \/ 1,000,000 elements respectively<\/li>\n<li>Have a pure JAXB client which would unmarshall the large XML files completely in memory<\/li>\n<li>Have a STax\/JAXB client which would combine the low-memory consumption of SAX technologies with the ease of programming model offered by JAXB<\/li>\n<li>Have a Woodstox\/JAXB client with the same characteristics of the STax\/JAXB client (in few words I just wanted to change the underlying parser and see if I could obtain any performance boost)<\/li>\n<li>Record both memory consumption and speed of processing (e.g. how quickly would each solution make XML chunks available in memory as JAXB domain model classes)<\/li>\n<li>Make the results available graphically, since, as we know, one picture tells one thousands words.<\/li>\n<\/ul>\n<p><strong> The Domain Model XML Schema<\/strong>  <\/p>\n<pre class=\"brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;schema xmlns=\"http:\/\/www.w3.org\/2001\/XMLSchema\" \r\ntargetNamespace=\"http:\/\/uk.co.jemos.integration.xml\/large-file\" \r\nxmlns:tns=\"http:\/\/uk.co.jemos.integration.xml\/large-file\" \r\nelementFormDefault=\"qualified\"&gt;\r\n\r\n    &lt;complexType name=\"PersonType\"&gt;\r\n        &lt;sequence&gt;\r\n            &lt;element name=\"firstName\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"lastName\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"address1\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"address2\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"postCode\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"city\" type=\"string\"&gt;&lt;\/element&gt;\r\n            &lt;element name=\"country\" type=\"string\"&gt;&lt;\/element&gt;\r\n        &lt;\/sequence&gt;\r\n        &lt;attribute name=\"active\" type=\"boolean\" use=\"required\" \/&gt;\r\n    &lt;\/complexType&gt;\r\n\r\n    &lt;complexType name=\"PersonsType\"&gt;\r\n        &lt;sequence&gt;\r\n            &lt;element name=\"person\" type=\"tns:PersonType\"                   \r\n            maxOccurs=\"unbounded\" minOccurs=\"1\"&gt;&lt;\/element&gt;\r\n        &lt;\/sequence&gt;\r\n    &lt;\/complexType&gt;\r\n\r\n    &lt;element name=\"persons\" type=\"tns:PersonsType\"&gt;\r\n    &lt;\/element&gt;\r\n&lt;\/schema&gt;\r\n<\/pre>\n<p>I decided for a relatively easy domain model, with XML elements representing people, with their names and addresses. I also wanted to record whether a person was active.<\/p>\n<p><strong>Using JAXB to create the Java model<\/strong><\/p>\n<p>I am a fan of Maven and use it as my default tool to build systems. This is the POM I defined for this little benchmark: <\/p>\n<pre class=\"brush:xml\">&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\r\nxmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\nxsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 \r\nhttp:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n\r\n   &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n   &lt;groupId&gt;uk.co.jemos.tests.xml&lt;\/groupId&gt;\r\n   &lt;artifactId&gt;large-xml-parser&lt;\/artifactId&gt;\r\n   &lt;version&gt;1.0.0-SNAPSHOT&lt;\/version&gt;\r\n   &lt;packaging&gt;jar&lt;\/packaging&gt;\r\n\r\n   &lt;name&gt;large-xml-parser&lt;\/name&gt;\r\n   &lt;url&gt;http:\/\/www.jemos.co.uk&lt;\/url&gt;\r\n\r\n   &lt;properties&gt; \r\n   &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\r\n   &lt;\/properties&gt;\r\n\r\n   &lt;build&gt;\r\n     &lt;plugins&gt;\r\n       &lt;plugin&gt;\r\n         &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n           &lt;artifactId&gt;maven-compiler-plugin&lt;\/artifactId&gt;\r\n           &lt;version&gt;2.3.2&lt;\/version&gt;\r\n           &lt;configuration&gt;\r\n             &lt;source&gt;1.6&lt;\/source&gt;\r\n             &lt;target&gt;1.6&lt;\/target&gt;\r\n           &lt;\/configuration&gt;\r\n         &lt;\/plugin&gt;\r\n        &lt;plugin&gt;\r\n          &lt;groupId&gt;org.jvnet.jaxb2.maven2&lt;\/groupId&gt;\r\n          &lt;artifactId&gt;maven-jaxb2-plugin&lt;\/artifactId&gt;\r\n          &lt;version&gt;0.7.5&lt;\/version&gt;\r\n          &lt;executions&gt;\r\n            &lt;execution&gt;\r\n              &lt;goals&gt;\r\n                &lt;goal&gt;generate&lt;\/goal&gt;\r\n              &lt;\/goals&gt;\r\n            &lt;\/execution&gt;\r\n          &lt;\/executions&gt;\r\n          &lt;configuration&gt;\r\n            &lt;schemaDirectory&gt;${basedir}\/src\/main\/resources&lt;\/schemaDirectory&gt;\r\n            &lt;includeSchemas&gt;\r\n              &lt;includeSchema&gt;**\/*.xsd&lt;\/includeSchema&gt;\r\n            &lt;\/includeSchemas&gt;\r\n            &lt;extension&gt;true&lt;\/extension&gt;\r\n            &lt;args&gt;\r\n              &lt;arg&gt;-enableIntrospection&lt;\/arg&gt;\r\n              &lt;arg&gt;-XtoString&lt;\/arg&gt;\r\n              &lt;arg&gt;-Xequals&lt;\/arg&gt;\r\n              &lt;arg&gt;-XhashCode&lt;\/arg&gt;\r\n            &lt;\/args&gt;\r\n            &lt;removeOldOutput&gt;true&lt;\/removeOldOutput&gt;\r\n            &lt;verbose&gt;true&lt;\/verbose&gt;\r\n            &lt;plugins&gt;\r\n              &lt;plugin&gt;\r\n                &lt;groupId&gt;org.jvnet.jaxb2_commons&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;jaxb2-basics&lt;\/artifactId&gt;\r\n                &lt;version&gt;0.6.1&lt;\/version&gt;\r\n              &lt;\/plugin&gt;\r\n            &lt;\/plugins&gt;\r\n          &lt;\/configuration&gt;\r\n        &lt;\/plugin&gt;\r\n        &lt;plugin&gt;\r\n          &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n          &lt;artifactId&gt;maven-jar-plugin&lt;\/artifactId&gt;\r\n          &lt;version&gt;2.3.1&lt;\/version&gt;\r\n          &lt;configuration&gt;\r\n            &lt;archive&gt;\r\n              &lt;manifest&gt;\r\n                &lt;addClasspath&gt;true&lt;\/addClasspath&gt;\r\n                &lt;mainClass&gt;uk.co.jemos.tests.xml.XmlPullBenchmarker&lt;\/mainClass&gt;\r\n              &lt;\/manifest&gt;\r\n            &lt;\/archive&gt;\r\n          &lt;\/configuration&gt;\r\n        &lt;\/plugin&gt;\r\n        &lt;plugin&gt;\r\n          &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n          &lt;artifactId&gt;maven-assembly-plugin&lt;\/artifactId&gt;\r\n          &lt;version&gt;2.2&lt;\/version&gt;\r\n          &lt;configuration&gt;\r\n\r\n&lt;outputDirectory&gt;${project.build.directory}\/site\/downloads&lt;\/outputDirectory&gt;\r\n            &lt;descriptors&gt;\r\n              &lt;descriptor&gt;src\/main\/assembly\/project.xml&lt;\/descriptor&gt;\r\n              &lt;descriptor&gt;src\/main\/assembly\/bin.xml&lt;\/descriptor&gt;\r\n            &lt;\/descriptors&gt;\r\n          &lt;\/configuration&gt;\r\n        &lt;\/plugin&gt;\r\n      &lt;\/plugins&gt;\r\n   &lt;\/build&gt;\r\n\r\n   &lt;dependencies&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;junit&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;junit&lt;\/artifactId&gt;\r\n       &lt;version&gt;4.5&lt;\/version&gt;\r\n       &lt;scope&gt;test&lt;\/scope&gt;\r\n     &lt;\/dependency&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;uk.co.jemos.podam&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;podam&lt;\/artifactId&gt;\r\n       &lt;version&gt;2.3.11.RELEASE&lt;\/version&gt;\r\n     &lt;\/dependency&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;commons-io&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;commons-io&lt;\/artifactId&gt;\r\n       &lt;version&gt;2.0.1&lt;\/version&gt;\r\n     &lt;\/dependency&gt;\r\n     &lt;!-- XML binding stuff --&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;com.sun.xml.bind&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;jaxb-impl&lt;\/artifactId&gt;\r\n       &lt;version&gt;2.1.3&lt;\/version&gt;\r\n     &lt;\/dependency&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;org.jvnet.jaxb2_commons&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;jaxb2-basics-runtime&lt;\/artifactId&gt;\r\n       &lt;version&gt;0.6.0&lt;\/version&gt;\r\n     &lt;\/dependency&gt;\r\n     &lt;dependency&gt;\r\n       &lt;groupId&gt;org.codehaus.woodstox&lt;\/groupId&gt;\r\n       &lt;artifactId&gt;stax2-api&lt;\/artifactId&gt;\r\n       &lt;version&gt;3.0.3&lt;\/version&gt;\r\n     &lt;\/dependency&gt;\r\n   &lt;\/dependencies&gt;\r\n&lt;\/project&gt;\r\n<\/pre>\n<p>Just few things to notice about this pom.xml. <div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<ul>\n<li>I use Java 6, since starting from version 6, Java contains all the XML libraries for JAXB, DOM, SAX and STax. <\/li>\n<li>To auto-generate the domain model classes from the XSD schema, I used the excellent maven-jaxb2-plugin, which allows, amongst other things, to obtain POJOs with toString, equals and hashcode support.<\/li>\n<\/ul>\n<div>\n<\/div>\n<p>I have also declared the jar plugin, to create an executable jar for the benchmark and the assembly plugin to distribute an executable version of the benchmark. The code for the benchmark is attached to this post, so if you want to build it and run it yourself, just unzip the project file, open a command line and run: <\/p>\n<p>$ mvn clean install assembly:assembly <\/p>\n<p>This command will place *-bin.* files into the folder target\/site\/downloads. Unzip the one of your preference and to run the benchmark use (-Dcreate.xml=true will generate the XML files. Don&#8217;t pass it if you have these files already, e.g. after the first run): <\/p>\n<p>$ java -jar -Dcreate.xml=true large-xml-parser-1.0.0-SNAPSHOT.jar <\/p>\n<p><strong>Creating the test data<\/strong>           <\/p>\n<p>To create the test data, I used <a href=\"http:\/\/www.jemos.eu\/projects\/podam\/index.html\" target=\"_blank\" title=\"PODAM - POjo DAta Mocker\">PODAM<\/a>, a Java tool to auto-fill POJOs and JavaBeans with data. The code is as simple as: <\/p>\n<pre class=\"brush:java\">JAXBContext context = JAXBContext.newInstance(\"xml.integration.jemos.co.uk.large_file\");\r\n    Marshaller marshaller = context.createMarshaller();\r\n    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);\r\n    marshaller.setProperty(Marshaller.JAXB_ENCODING, \"UTF-8\");\r\n\r\n    PersonsType personsType = new ObjectFactory().createPersonsType();\r\n    List&lt;PersonType&gt; persons = personsType.getPerson();\r\n    PodamFactory factory = new PodamFactoryImpl();\r\n    for (int i = 0; i &lt; nbrElements; i++) {\r\n        persons.add(factory.manufacturePojo(PersonType.class));\r\n    }\r\n\r\n    JAXBElement&lt;PersonsType&gt; toWrite = new ObjectFactory().createPersons(personsType);\r\n    File file = new File(fileName);\r\n    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file), 4096);\r\n\r\n    try {\r\n        marshaller.marshal(toWrite, bos);\r\n        bos.flush();\r\n    } finally {\r\n              IOUtils.closeQuietly(bos);\r\n      }\r\n<\/pre>\n<p>The XmlPullBenchmarker generates three large XML files under ~\/xml-benchmark: <\/p>\n<ul>\n<li>large-person-10000.xml (Approx 3M)<\/li>\n<li>large-person-100000.xml (Approx 30M)<\/li>\n<li>large-person-1000000.xml (Approx 300M)<\/li>\n<\/ul>\n<div>\n<\/div>\n<p>Each file looks like the following: <\/p>\n<pre class=\"brush:java\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?&gt;\r\n&lt;persons xmlns=\"http:\/\/uk.co.jemos.integration.xml\/large-file\"&gt;\r\n  &lt;person active=\"false\"&gt;\r\n    &lt;firstName&gt;Ult6yn0D7L&lt;\/firstName&gt;\r\n    &lt;lastName&gt;U8DJoUTlK2&lt;\/lastName&gt;\r\n    &lt;address1&gt;DxwlpOw6X3&lt;\/address1&gt;\r\n    &lt;address2&gt;O4GGvxIMo7&lt;\/address2&gt;\r\n    &lt;postCode&gt;Io7Kuz0xmz&lt;\/postCode&gt;\r\n    &lt;city&gt;lMIY1uqKXs&lt;\/city&gt;\r\n    &lt;country&gt;ZhTukbtwti&lt;\/country&gt;\r\n  &lt;\/person&gt;\r\n\r\n  &lt;person active=\"false\"&gt;\r\n    &lt;firstName&gt;gBc7KeX9Tn&lt;\/firstName&gt;\r\n    &lt;lastName&gt;kxmWNLPREp&lt;\/lastName&gt;\r\n    &lt;address1&gt;9BIBS1m5GR&lt;\/address1&gt;\r\n    &lt;address2&gt;hmtqpXjcpW&lt;\/address2&gt;\r\n    &lt;postCode&gt;bHpF1rRldM&lt;\/postCode&gt;\r\n    &lt;city&gt;YDJJillYrw&lt;\/city&gt;\r\n    &lt;country&gt;xgsTDJcfjc&lt;\/country&gt;\r\n  &lt;\/person&gt;\r\n\r\n[..etc]\r\n&lt;\/persons&gt;\r\n<\/pre>\n<p>Each file contains 10,000 \/ 100,000 \/ 1,000,000 &lt;person&gt; elements.<\/p>\n<p><strong>The running environments<\/strong>           <\/p>\n<p>I tried the benchmarker on three different environments:            <\/p>\n<ul>\n<li><strong>Ubuntu 10, 64-bit running as Virtual Machine<\/strong> on a Windows 7 ultimate, with CPU i5, 750 @2.67GHz and 2.66GHz, 8GB RAM of which 4GB dedicated to the VM. JVM: 1.6.0_25, Hotspot<\/li>\n<li><strong>Windows 7 Ultimate<\/strong>, hosting the above VM, therefore with same processor. JVM, 1.6.0_24, Hotspot<\/li>\n<li><strong>Ubuntu 10, 32-bit<\/strong>, 3GB RAM, dual core. JVM, 1.6.0_24, OpenJDK<\/li>\n<\/ul>\n<div>\n<\/div>\n<p><strong>The XML unmarshalling<\/strong>           <\/p>\n<p>To unmarshall the code I used three different strategies:            <\/p>\n<ul>\n<li>Pure JAXB <\/li>\n<li>STax + JAXB<\/li>\n<li>Woodstox + JAXB<\/li>\n<\/ul>\n<div>\n<\/div>\n<p><strong>Pure JAXB unmarshalling<\/strong>           <\/p>\n<p>The code which I used to unmarshall the large XML files using JAXB follows: <\/p>\n<pre class=\"brush:java\">private void readLargeFileWithJaxb(File file, int nbrRecords) throws Exception {\r\n        \r\n       JAXBContext ucontext = JAXBContext.newInstance(\"xml.integration.jemos.co.uk.large_file\");\r\n       Unmarshaller unmarshaller = ucontext.createUnmarshaller();\r\n       BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));\r\n       long start = System.currentTimeMillis();\r\n       long memstart = Runtime.getRuntime().freeMemory();\r\n       long memend = 0L;\r\n\r\n       try {\r\n          JAXBElement&lt;PersonsType&gt; root = (JAXBElement&lt;PersonsType&gt;) unmarshaller.unmarshal(bis);\r\n          root.getValue().getPerson().size();\r\n          memend = Runtime.getRuntime().freeMemory();\r\n          long end = System.currentTimeMillis();\r\n          LOG.info(\"JAXB (\" + nbrRecords + \"): - Total Memory used: \" + (memstart - memend));\r\n          LOG.info(\"JAXB (\" + nbrRecords + \"): Time taken in ms: \" + (end - start));\r\n       } finally {\r\n            IOUtils.closeQuietly(bis);\r\n         }\r\n}\r\n<\/pre>\n<p>The code uses a one-liner to unmarshall each XML file: <\/p>\n<pre class=\"brush:java\">JAXBElement&lt;PersonsType&gt; root = (JAXBElement&lt;PersonsType&gt;) unmarshaller.unmarshal(bis);\r\n<\/pre>\n<p>I also accessed the size of the underlying PersonType collection to &#8220;touch&#8221; in memory data. BTW, debugging the application showed that all 10,000 elements were indeed available in memory after this line of code.<\/p>\n<p><strong>JAXB + STax<\/strong>           <\/p>\n<p>With STax, I just had to use an XMLStreamReader, iterate through all &lt;person&gt; elements, and pass each in turn to JAXB to unmarshall it into a PersonType domain model object. The code follows: <\/p>\n<pre class=\"brush:java\">\/\/ set up a StAX reader\r\nXMLInputFactory xmlif = XMLInputFactory.newInstance();\r\nXMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(file));\r\nJAXBContext ucontext = JAXBContext.newInstance(PersonType.class);\r\nUnmarshaller unmarshaller = ucontext.createUnmarshaller();\r\nlong start = System.currentTimeMillis();\r\nlong memstart = Runtime.getRuntime().freeMemory();\r\nlong memend = 0L;\r\n\r\ntry {\r\n   xmlr.nextTag();\r\n   xmlr.require(XMLStreamConstants.START_ELEMENT, null, \"persons\");\r\n   \r\n   xmlr.nextTag();\r\n   while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT) {\r\n   \r\n       JAXBElement&lt;PersonType&gt; pt = unmarshaller.unmarshal(xmlr,PersonType.class);\r\n\r\n       if (xmlr.getEventType() == XMLStreamConstants.CHARACTERS) {\r\n           xmlr.next();\r\n       }\r\n   }\r\n\r\n   memend = Runtime.getRuntime().freeMemory();\r\n   long end = System.currentTimeMillis();\r\n   LOG.info(\"STax - (\" + nbrRecords + \"): - Total memory used: \" + (memstart - memend));\r\n   LOG.info(\"STax - (\" + nbrRecords + \"): Time taken in ms: \" + (end - start));\r\n   } finally {\r\n     xmlr.close();\r\n     }\r\n}\r\n<\/pre>\n<p>Note that this time when creating the context, I had to specify that it was for the PersonType object, and when invoking the JAXB unmarshalling I had to pass also the desired returned class type, with: <\/p>\n<pre class=\"brush:java\">JAXBElement&lt;PersonType&gt; pt = unmarshaller.unmarshal(xmlr, PersonType.class);\r\n<\/pre>\n<p>Note that I don&#8217;t to anything with the object, just create it, to keep the benchmark as truthful and possible by not introducing any unnecessary steps.<\/p>\n<p><strong>JAXB + Woodstox<\/strong><\/p>\n<p>With Woodstox, the approach is very similar to the one used with STax. In fact Woodstox provides a STax2 compatible API, so all I had to do was to provide the correct factory and&#8230;bang! I had Woodstox under the cover working. <\/p>\n<pre class=\"brush:java\">private void readLargeXmlWithFasterStax(File file, int nbrRecords)\r\n       throws FactoryConfigurationError, XMLStreamException,FileNotFoundException, JAXBException {\r\n\r\n   \/\/ set up a Woodstox reader\r\n   XMLInputFactory xmlif = XMLInputFactory2.newInstance();\r\n   XMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(file));\r\n   JAXBContext ucontext = JAXBContext.newInstance(PersonType.class);\r\n   Unmarshaller unmarshaller = ucontext.createUnmarshaller();\r\n   long start = System.currentTimeMillis();\r\n   long memstart = Runtime.getRuntime().freeMemory();\r\n\r\n   long memend = 0L;\r\n\r\n   try {\r\n       xmlr.nextTag();\r\n       xmlr.require(XMLStreamConstants.START_ELEMENT, null, \"persons\");\r\n       xmlr.nextTag();\r\n\r\n       while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT) {\r\n\r\n            JAXBElement&lt;PersonType&gt; pt = unmarshaller.unmarshal(xmlr,PersonType.class);\r\n\r\n               if (xmlr.getEventType() == XMLStreamConstants.CHARACTERS) {\r\n                   xmlr.next();\r\n               }\r\n       }\r\n\r\n       memend = Runtime.getRuntime().freeMemory();\r\n       long end = System.currentTimeMillis();\r\n       LOG.info(\"Woodstox - (\" + nbrRecords + \"): Total memory used: \" + (memstart - memend));\r\n       LOG.info(\"Woodstox - (\" + nbrRecords + \"): Time taken in ms: \" + (end - start));\r\n       } finally {\r\n         xmlr.close();\r\n        }\r\n}\r\n<\/pre>\n<p>Note the following line: <\/p>\n<pre class=\"brush:java\">XMLInputFactory xmlif = XMLInputFactory2.newInstance();\r\n<\/pre>\n<p>Where I pass in a STax2 XMLInputFactory. This uses the Woodstox implementation. <\/p>\n<p><strong>The main loop<\/strong>  <\/p>\n<p>Once the files are in place (you obtain this by passing -Dcreate.xml=true), the main performs the following: <\/p>\n<pre class=\"brush:java\">System.gc();\r\nSystem.gc();\r\n\r\nfor (int i = 0; i &lt; 10; i++) {\r\n    main.readLargeFileWithJaxb(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-10000.xml\"), 10000);\r\n    main.readLargeFileWithJaxb(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-100000.xml\"), 100000);\r\n    main.readLargeFileWithJaxb(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-1000000.xml\"), 1000000);\r\n    main.readLargeXmlWithStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-10000.xml\"), 10000);\r\n    main.readLargeXmlWithStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-100000.xml\"), 100000);\r\n    main.readLargeXmlWithStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-1000000.xml\"), 1000000);\r\n    main.readLargeXmlWithFasterStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-10000.xml\"), 10000);\r\n    main.readLargeXmlWithFasterStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-100000.xml\"), 100000);\r\n    main.readLargeXmlWithFasterStax(new File(OUTPUT_FOLDER + File.separatorChar + \"large-person-1000000.xml\"), 1000000);\r\n}\r\n<\/pre>\n<p>It invites the GC to run, although as we know this is at the GC Thread discretion. It then executes each <em>strategy <\/em>10 times, to <em>normalise <\/em>RAM and CPU consumption. The final data are then collected by running an average on the ten runs. <\/p>\n<p><strong>The benchmark results for memory consumption<\/strong>  <\/p>\n<p>Here follow some diagrams which show memory consumption across the different running environments, when unmarshalling 10,000 \/ 100,000 \/ 1,000,000 files. <\/p>\n<p>You will probably notice that memory consumption for STax-related strategies often shows a negative value. This means that there was more free memory after unmarshalling all elements than there was at the beginning of the unmarshalling loop; this, in turn, suggests that the GC ran a lot more with STax than with JAXB. This is logical if one thinks about it; since with STax we don&#8217;t keep all objects into memory there are more objects available for garbage collection. In this particular case I believe the PersonType object created in the while loop gets eligible for GC and enters the young generation area and then it gets reclamed by the GC. This, however, should have a minimum impact on performance, since we know that claiming objects from the young generation space is done very efficiently.<\/p>\n<p><strong>Summary for 10,000 XML elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/2.bp.blogspot.com\/-0H8fMxsNnyE\/T74kT1BFQwI\/AAAAAAAAAQ0\/SUVDlNgn118\/s1600\/6a0120a6e4cce1970b01538f746280970b.png\"><img decoding=\"async\" border=\"0\" height=\"332\" src=\"http:\/\/2.bp.blogspot.com\/-0H8fMxsNnyE\/T74kT1BFQwI\/AAAAAAAAAQ0\/SUVDlNgn118\/s640\/6a0120a6e4cce1970b01538f746280970b.png\" width=\"640\" \/><\/a><\/div>\n<p><strong>Summary for 100,000 XML elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/4.bp.blogspot.com\/-xHSPXmglpkw\/T74kkIRdyxI\/AAAAAAAAAQ8\/wQnJQH2PT2g\/s1600\/6a0120a6e4cce1970b01543347bbb7970c.png\"><img decoding=\"async\" border=\"0\" height=\"316\" src=\"http:\/\/4.bp.blogspot.com\/-xHSPXmglpkw\/T74kkIRdyxI\/AAAAAAAAAQ8\/wQnJQH2PT2g\/s640\/6a0120a6e4cce1970b01543347bbb7970c.png\" width=\"640\" \/><\/a><\/div>\n<p><strong>Summary for 1,000,000 XML elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/3.bp.blogspot.com\/-m0Ra0locLsA\/T74kxS-ow4I\/AAAAAAAAARE\/8CAc-1rl9Xo\/s1600\/6a0120a6e4cce1970b014e8967cc2c970d.png\"><img decoding=\"async\" border=\"0\" height=\"310\" src=\"http:\/\/3.bp.blogspot.com\/-m0Ra0locLsA\/T74kxS-ow4I\/AAAAAAAAARE\/8CAc-1rl9Xo\/s640\/6a0120a6e4cce1970b014e8967cc2c970d.png\" width=\"640\" \/><\/a><\/div>\n<p><strong>The benchmark results for processing speed<\/strong><\/p>\n<p><strong>Results for 10,000 elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/2.bp.blogspot.com\/-QbZYRoLY2Tk\/T74lZKBYLBI\/AAAAAAAAARM\/g-1KaIDXHn0\/s1600\/6a0120a6e4cce1970b01543347bcf7970c.png\"><img decoding=\"async\" border=\"0\" height=\"323\" src=\"http:\/\/2.bp.blogspot.com\/-QbZYRoLY2Tk\/T74lZKBYLBI\/AAAAAAAAARM\/g-1KaIDXHn0\/s640\/6a0120a6e4cce1970b01543347bcf7970c.png\" width=\"640\" \/><\/a><\/div>\n<div class=\"separator\" style=\"clear: both;text-align: center\">\n<\/div>\n<p><strong>Results for 100,000 elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/3.bp.blogspot.com\/-06qBA6JdCiI\/T74llB7DbfI\/AAAAAAAAARU\/c_N-eD6C5uQ\/s1600\/6a0120a6e4cce1970b014e8967cd3a970d.png\"><img decoding=\"async\" border=\"0\" height=\"280\" src=\"http:\/\/3.bp.blogspot.com\/-06qBA6JdCiI\/T74llB7DbfI\/AAAAAAAAARU\/c_N-eD6C5uQ\/s640\/6a0120a6e4cce1970b014e8967cd3a970d.png\" width=\"640\" \/><\/a><\/div>\n<p><strong>Results for 1,000,000 elements<\/strong><\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/2.bp.blogspot.com\/-wYH067Kg_aM\/T74lyhZLBDI\/AAAAAAAAARc\/MKLkhPb3w14\/s1600\/6a0120a6e4cce1970b01538f74680e970b.png\"><img decoding=\"async\" border=\"0\" height=\"294\" src=\"http:\/\/2.bp.blogspot.com\/-wYH067Kg_aM\/T74lyhZLBDI\/AAAAAAAAARc\/MKLkhPb3w14\/s640\/6a0120a6e4cce1970b01538f74680e970b.png\" width=\"640\" \/><\/a><\/div>\n<p><strong>Conclusions<\/strong><\/p>\n<p>The results on all three different environments, although with some differences, all tell us the same story:            <\/p>\n<ul>\n<li><strong>If you are looking for performance (e.g. XML unmarshalling speed), choose JAXB<\/strong><\/li>\n<li><strong>If you are looking for low-memory usage (and are ready to sacrifice some performance speed), then use STax.<\/strong><\/li>\n<\/ul>\n<p>My personal opinion is also that I wouldn&#8217;t go for Woodstox, but I&#8217;d choose either JAXB (if I needed processing power and could afford the RAM) or STax (if I didn&#8217;t need top speed and was low on infrastructure resources). Both these technologies are Java standards and part of the JDK starting from Java 6.<\/p>\n<p><strong>Resources Benchmarker source code<\/strong>  <\/p>\n<ul>\n<li>Zip version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-project.zip\">Download Large-xml-parser-1.0.0-SNAPSHOT-project<\/a><\/li>\n<li>tar.gz version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-project.tar.gz\">Download Large-xml-parser-1.0.0-SNAPSHOT-project.tar<\/a><\/li>\n<li>tar.bz2 version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-project.tar.bz2\">Download Large-xml-parser-1.0.0-SNAPSHOT-project.tar<\/a><\/li>\n<\/ul>\n<p><strong>Benchmarker executables:<\/strong>           <\/p>\n<ul>\n<li>Zip version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-bin.zip\">Download Large-xml-parser-1.0.0-SNAPSHOT-bin<\/a><\/li>\n<li>tar.gz version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-bin.tar.gz\">Download Large-xml-parser-1.0.0-SNAPSHOT-bin.tar<\/a><\/li>\n<li>tar.bz2 version: <a href=\"http:\/\/tedone.typepad.com\/files\/large-xml-parser-1.0.0-snapshot-bin.tar.bz2\">Download Large-xml-parser-1.0.0-SNAPSHOT-bin.tar<\/a><\/li>\n<\/ul>\n<div>\n<\/div>\n<p><strong>Data files:<\/strong>           <\/p>\n<ul>\n<li>Ubuntu 64-bit VM running environment: <a href=\"http:\/\/tedone.typepad.com\/files\/stax-vs-jaxb-ubuntu-64-vm.xlsx\">Download Stax-vs-jaxb-ubuntu-64-vm<\/a><\/li>\n<li>Ubuntu 32-bit running environment: <a href=\"http:\/\/tedone.typepad.com\/files\/stax-vs-jaxb-ubuntu-32-bit.xlsx\">Download Stax-vs-jaxb-ubuntu-32-bit<\/a><\/li>\n<li>Windows 7 Ultimate running environment: <a href=\"http:\/\/tedone.typepad.com\/files\/stax-vs-jaxb-windows7.xlsx\">Download Stax-vs-jaxb-windows7<\/a><\/li>\n<\/ul>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/tedone.typepad.com\/blog\/2011\/06\/unmarshalling-benchmark-in-java-jaxb-vs-stax-vs-woodstox.html\">XML unmarshalling benchmark in Java: JAXB vs STax vs Woodstox <\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Marco Tedone at the <a href=\"http:\/\/tedone.typepad.com\/blog\/\">Marco Tedone&#8217;s blog<\/a> blog.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I wanted to solve was how to process large XML files in chunks while at the same time providing upstream\/downstream systems with some data to process. Of course I&#8217;ve &hellip;<\/p>\n","protected":false},"author":188,"featured_media":97,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[487,488,144],"class_list":["post-1216","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-codehaus-stax","tag-codehaus-woodstox","tag-jaxb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-05-24T16:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-22T05:04:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Marco Tedone\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marco Tedone\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html\"},\"author\":{\"name\":\"Marco Tedone\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/d884fc40a7928d9a02b9abdd245454cb\"},\"headline\":\"XML unmarshalling benchmark: JAXB vs STax vs Woodstox\",\"datePublished\":\"2012-05-24T16:00:00+00:00\",\"dateModified\":\"2012-10-22T05:04:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html\"},\"wordCount\":1769,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/codehaus-logo.jpg\",\"keywords\":[\"Codehaus StAX\",\"Codehaus Woodstox\",\"JAXB\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html\",\"name\":\"XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/codehaus-logo.jpg\",\"datePublished\":\"2012-05-24T16:00:00+00:00\",\"dateModified\":\"2012-10-22T05:04:17+00:00\",\"description\":\"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/codehaus-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/codehaus-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/05\\\/xml-unmarshalling-benchmark-jaxb-vs.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"XML unmarshalling benchmark: JAXB vs STax vs Woodstox\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/d884fc40a7928d9a02b9abdd245454cb\",\"name\":\"Marco Tedone\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g\",\"caption\":\"Marco Tedone\"},\"sameAs\":[\"http:\\\/\\\/tedone.typepad.com\\\/blog\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Marco-Tedone\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks","description":"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html","og_locale":"en_US","og_type":"article","og_title":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks","og_description":"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I","og_url":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-05-24T16:00:00+00:00","article_modified_time":"2012-10-22T05:04:17+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg","type":"image\/jpeg"}],"author":"Marco Tedone","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Marco Tedone","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html"},"author":{"name":"Marco Tedone","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/d884fc40a7928d9a02b9abdd245454cb"},"headline":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox","datePublished":"2012-05-24T16:00:00+00:00","dateModified":"2012-10-22T05:04:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html"},"wordCount":1769,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg","keywords":["Codehaus StAX","Codehaus Woodstox","JAXB"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html","url":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html","name":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg","datePublished":"2012-05-24T16:00:00+00:00","dateModified":"2012-10-22T05:04:17+00:00","description":"Introduction Towards the end of last week I started thinking how to deal with large amounts of XML data in a resource-friendly way.The main problem that I","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/codehaus-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/05\/xml-unmarshalling-benchmark-jaxb-vs.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"XML unmarshalling benchmark: JAXB vs STax vs Woodstox"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/d884fc40a7928d9a02b9abdd245454cb","name":"Marco Tedone","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/879705fe0135d585e6a86a344d08e4ef35e98040233b855eb7ea543cb5a891ed?s=96&d=mm&r=g","caption":"Marco Tedone"},"sameAs":["http:\/\/tedone.typepad.com\/blog\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Marco-Tedone"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/188"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=1216"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1216\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/97"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=1216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=1216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=1216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}