Desenvolvimento

14 dez, 2012

Transformação de desempenho de XML: Groovy vs XSLT

Publicidade

Existe uma boa variedade de opções disponíveis para transformar XML. Além dos padrões (XSLT e XQuery), o Groovy possui suporte excelente de manipulação de XML com MarkupBuilders e XMLSlurpers.

Eu queria saber como XSLT e Groovy se comparam em termos de desempenho, mas não consegui encontrar material sobre isso online. Então, eu decidi medir eu mesmo.

AVISO: Eu tentei ao máximo fazer a comparação justa. Por exemplo, eu mantive tanto o XML e a transformação lógica tão simples quanto possível. Dito isso, os passos exatos que cada transformação segue não são idênticos, e isso pode ter afetado os resultados. Além disso, eu usei bibliotecas com padrão Java com base em Xalan (javax.xml.transform.*) para executar o código XSLT. Pode ser possível obter melhores resultados com Saxon.

Os meus resultados mostram que o Groovy foi consistentemente mais rápido, cerca de 44% em média. Os detalhes dos meus testes são apresentados abaixo.

O teste

Aqui está o XML que eu queria transformar:

<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>

Eu escrevi duas transformações, em XSLT e em Groovy, para gerar uma página HTML simples. Aqui está o 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>

E aqui está o 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()
Então eu rodei duas transformações e cronometrei seus resultados de execução:
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)

O resultados

Rodei três conjuntos de comparações (100 vezes cada um, transformando um documento XML com mil itens). Os resultados são apresentados a seguir:

run 1

run 2

run 3

 

***

Texto original disponível em http://tatiyants.com/xml-transformation-performance-groovy-vs-xslt/