This article lists some techniques to improve the
performance of Extensible Stylesheet Language (XSL) Transformations. XSL is a
functional language. XSL does not support features of common language. For
example, XSL does not support return values, or globals. XSL is not an
object-oriented language, and being modular costs processor cycles. There is no
debug available for XSL, therefore, the debugging becomes
difficult.
Performance of an XSL transformation depends on the
scenarios that you use. The techniques that are listed in this article are
general guidelines. Make sure that you measure the results of each tuning. Only
testing can prove whether a particular technique improves the performance or
not. You can use the msxsl.exe command line utility for testing, and to perform
command line XSL transformations by using the Microsoft XSL processor. The
msxsl.exe utility invokes the Microsoft XML Parser 4.0 (msxml4.dll) to perform
the transformation. You can download this utility from the following MSDN
site:
Identify the most common code paths to render your pages,
and then optimize these paths. Optimize the highly re-used sections of
XSL.
Instead of using sub-elements, use attributes wherever
possible. Using attributes instead of elements improves the performance. When
performing XPath matches, attributes are faster because they are loosely typed.
This makes validation of the schema easier.
Use more explicit paths instead of "//" wherever possible.
When XML data is large, "//" recursive decedent search is very expensive.
Specific XPath expression implements faster.
When you match against attribute values, use enumerator
attributes. Use multiple attribute names as bits, and set their values to true or false. For example:
<element_name attr1="1" attr2="1" attr3="0">
Do not use script. Using script downgrades the
performance.
Compare directly by name to improve the performance. For
example, instead of using the following code:
./info[type='title']
use the following code:
./title
When you compare values, instead of using name as follows:
Select="*[name()='sample']"
use the following code:
Select="sample"
Because of the namespace handling in XPath, these are not exactly
equivalent.
All versions of MSXML, Version 3.0 and later, are faster
with the explicit index filter. The improvement in performance depends on the
position of the element in the child list of the parent. Instead of using the
following:
/child_element
use the following:
/child_element[1]
Use parameters instead of evaluating the query each
time.
XSL Transformations allows multiple options, however, all
of them may not perform adequately. For example, instead of using the following
transformation:
<xsl:output method="html"/>
use the following transformation:
<xsl:output method="html" indent="no" />
This improves performance because indentation provides a lot of unwanted
white spaces in the output. By default, the value for the attribute indent is yes.
Inline the template with for-each or mode attribute when you are sure that your apply-template matches exactly one template. For example:
is evaluated on all other templates with the same mode. Processor starts
to run default templates. This copies all text nodes, and calls the following:
<xsl:apply-templates>
for all elements. Therefore, for all children of original nodeset,
possible matches expression is evaluated. Matching the expression is not a
simple task. To improve the performance, rewrite the code as follows:
Use fewer templates. This is applicable when you run the
same template more than one time. There is some improvement in performance with
tight for-each loop to search for a template when the number of templates are
less.
Reduce the usage of xsl:choose/xsl:when/xsl:otherwise. Performance is effected when the majority of selections fall
through the otherwise clause. Therefore, match with when, and try to avoid using otherwise when you know that a particular value exists.
xsl:variables are dynamic values. These variables are not
in cache, and run every time that they are referenced in XSL. Explicit type
casting of xsl:variable improves the performance. You can do type casting with string() and boolean() functions. For example:
MSXML parser is different from XmlReader and XmlWriter.
MSXML loads XML data into a Document Object Model
(DOM). From this DOM tree, data can easily be navigated through XPath,
transformed through XSL, or edited and saved back. This enables easier
development and more powerful capabilities at the expense of memory usage and
speed.
XmlReader and XmlWriter are sequential readers and writers. The developer maintains state
manually when reading and writing XML data. This allows the minimal memory
usage and, therefore, improves the performance.
The MSXML parser also supports SAX (Simple API for
XML). SAX is sequential. The .NET framework also supports the DOM by using the XmlDocument class.
The best choice depends on the utilization of .NET
framework and on the task that you perform with XML.
This technique is related to the performance with database.
MSXML and System.Xml performance can be improved in pre-joining the lookup
fields as shown in the following code: