There’s a good variety of options available for transforming XML. In addition to the standards (XSLT and XQuery), Groovy has excellent XML manipulation support with MarkupBuilders and XMLSlurpers.

I wanted to know how XSLT and Groovy compare in terms of performance, but couldn’t find anything online. So, I decided to measure it myself.

DISCLAIMER: I tried as much as I could to make the comparison fair. For instance, I kept both the XML and the transform logic as simple as possible. That said, exact steps each transform follows aren’t identical and that may have impacted the results. Moreover, I used standard java libraries based on Xalan (javax.xml.transform.*) to execute the XSLT code. It may be possible to get better results with Saxon.

My results show that Groovy was consistently faster, about 44% on average. The details of my tests are shown below.

The Test

Here’s the XML I wanted to transform:

<items>
  <item>
    <id>1</id>
    <name>ZVHHNW73O</name>
  </item>
  <item>
    <id>2</id>
    <name>3T4HDAPOX</name>
  </item>
  <item>
    <id>3</id>
    <name>LUHQSSYMA</name>
  </item>
  <item>
    <id>4</id>
    <name>PA6H6PVJ9</name>
  </item>
</items>

I wrote two transforms, in XSLT and in Groovy, to generate a simple HTML page. Here’s the XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
                <title>list of items</title>
            </head>
            <body>
                <h1>items</h1>
                <ul>
                    <xsl:apply-templates select="items/item" />
                </ul>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="item">
        <li>
            <xsl:value-of select="name"/>
        </li>
    </xsl:template>
</xsl:stylesheet>

And here’s the Groovy:

def inXml = new XmlSlurper().parse(xmlFile)
def writer = new StringWriter()
def outXml = new MarkupBuilder(writer)

outXml.html {
    head {
        title {'list of items'}
    }
    body {
        h1 {'items'}
        ul {
            inXml.item.each {
               li(it.name.text())
            }
        }
    }
}
writer.toString()

I then ran both transforms and timed their execution results:

xsltTransformer = factory.newTransformer(new StreamSource(new FileReader(xsltPath)))
xml = new FileReader(xmlPath)
groovyTransformer = new GroovyXmlTransformer()

xsltStart = new Date()
xsltTransformer.transform(new StreamSource(xml), new StreamResult(System.out))
xsltStop = new Date()
xslElapsed =  TimeCategory.minus(xsltStop, xsltStart)

groovyStart = new Date()
groovyTransformer.transform(new FileReader(xmlPath))
groovyStop = new Date()
groovyElapsed = TimeCategory.minus(groovyStop, groovyStart)

The Results

I ran three sets of comparisons (100 times each, transforming an XML document with a 1,000 items). The results are shown below:

run 1

run 2

run 3

You may also like:

Did you love / hate / were unmoved by this post?
Then show your support / disgust / indifference by following me on Twitter!

Comments are closed.