XSLT optimizations for performance improvements

XSLT optimizations for performance improvements

book

Article ID: KB0070465

calendar_today

Updated On:

Products Versions
TIBCO ActiveMatrix BusinessWorks 6.x

Description

This articles discusses XSLT optimizations that result in the performance improvement.

Definitions:

Predicates : In simple words anything written inside [] in the xslt evaluation is a predicate. It is usually used to restrict the selected nodes based on the condition given inside the brackets.

For each loop : This refers to the evaluations carried out inside the <xsl:for-each> declarations

Variable : Variables can be defined and assigned calculated values in xslt by writing <xsl:variable> declarations. The name attribute of this declaration gives the variable name and select clause evaluates the value of the variable. It can be nodes, primitive types, user defined types etc.
 

Issue/Introduction

XSLT optimizations for performance improvements

Resolution

Review the predicates and expression evaluations both inside and outside the for each loop in the xslt. In case of predicates, pre calculating the predicate's clause can help with performance.
If the xslt processing takes up majority of the time in for-each processing and the logic inside for-each has a lot of predicate calculations that are not affected by the changing focus of for-each then we may shift the predicates out of the for-each loop in xslt.

Let's take a look at the following xslt:

<xsl:for-each select="ns:messages">
                                    <xsl:choose>
                                        <xsl:when test="$lookup/lookup[@id = &quot;filtervar&quot;]/map">
                                            <root>
                                                <xsl:if test="$lookup/lookup[@id = &quot;filtervar&quot;]/map">
                                                    <xsl:attribute name="ShortText">
                                                        <xsl:value-of select="$lookup/lookup[@id = &quot;filtervar&quot;]/map"/>
                                                    </xsl:attribute>
                                                </xsl:if>
                                                <xsl:if test="$lookup/lookup[@id = &quot;filtervar&quot;]/list">
                                                    <xsl:attribute name="Type">
                                                        <xsl:value-of select="$lookup/lookup[@id = &quot;filtervar&quot;]/list"/>
                                                    </xsl:attribute>
                                                </xsl:if>
                                                <xsl:value-of select="$lookup/lookup[@id = &quot;filtervar&quot;]/list"/>
                                            </root>
                                        </xsl:when>
                                    </xsl:choose>
                                </xsl:for-each>

Here if we know that if the inputs to $lookup/lookup[@id = &quot;filtervar&quot;]/list and $lookup/lookup[@id = &quot;filtervar&quot;]/map are not related to the select clause in for-each we may safely shift them outside the for-each loop into variables calculated once and referred multiple times.

Here the calculation of map and list predicates happens 3 times each for each loop. So if the for-each runs for 500 iterations we are calculating predicates 500 * 3 * 2 times = 3000

<xsl:variable name="varlist" select="$lookup/lookup[@id = &quot;filtervar&quot;]/list"/>
<xsl:variable name="varmap" select="$lookup/lookup[@id = &quot;filtervar&quot;]/map"/>
<xsl:for-each select="ns:messages">
                                    <xsl:choose>
                                        <xsl:when test="$varmap">
                                            <root>
                                                <xsl:if test="$varmap">
                                                    <xsl:attribute name="ShortText">
                                                        <xsl:value-of select="$varmap"/>
                                                    </xsl:attribute>
                                                </xsl:if>
                                                <xsl:if test="$varlist">
                                                    <xsl:attribute name="Type">
                                                        <xsl:value-of select="$varlist"/>
                                                    </xsl:attribute>
                                                </xsl:if>
                                                <xsl:value-of select="$varlist"/>
                                            </root>
                                        </xsl:when>
                                    </xsl:choose>
                                </xsl:for-each>

Now the variables varmap and varlist are calculated only once and only the value is referred inside the for loop. So they are calculated only 2 times irrespective of the number of times for loop runs.