Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT document() : Is it slower when calling it multiple times?

Tags:

java

xml

xslt

xalan

UPDATE 17.Jul.2013:
XALAN 2.7 does not cache document() calls within a request. So it is crucial to store each needed document in a variable in the XSL.


I have searched for quite a while and didn't find concrete answers to my simple question:

Which approach is faster or is the compiler "smart" enough so that both variants are the same?

Note: I am using Xalan 2.7 (default implementation in JDK 1.6):

1) I have to read a property in an external XML:

<xsl:value-of select="document($path)/person/address/city"/>

Whenever I need the city, I use the expression above (let's say 100 times)

2) Instead of calling the document() 100 times, I store the XML node in a variable:

<xsl:variable name="node" select="document($path)"/>

And then I use 100 times

<xsl:value-of select="$node/person/address/city"/>

Which one is faster, better, for which reasons? Thank you!

like image 459
basZero Avatar asked May 10 '11 07:05

basZero


2 Answers

Both methods should execute for the same time if an XSLT processor is not naive, because the document function should return the same result when it is called with the same argument(s), no matter how many times.

Both methods are not efficient, because of the use of the // abbreviation, which causes the whole document tree to be traversed.

I would recommend the following as more efficient than both methods are being discussed:

<xsl:variable name="vCities" select="document($pUrl)//cities"/>

then only reference $vCities.

In this way you have traversed the document only once.

like image 195
Dimitre Novatchev Avatar answered Oct 21 '22 22:10

Dimitre Novatchev


It seems that you understand the principles involved, so you don't need any explanations there.

If you want to know how Xalan 2.7 does it, the definitive answer will be found by testing it with Xalan 2.7, with a large enough test.

As @Dimitre noted, neither one of these is necessarily efficient, because of the //, though some processors are smart about optimizing those kinds of paths, mitigating the problem. You could help the processor be more efficient by keeping the city element in a variable:

<xsl:variable name="city" select="(document($path)//city)[1]"/>
...
<xsl:value-of select="$city"/>

I added [1] in there for further optimization because you said "the city" (i.e. you expect only one), and this allows a smart processor to stop after it finds the first city element.

like image 45
LarsH Avatar answered Oct 21 '22 23:10

LarsH