RE: [xsl] Performance

Subject: RE: [xsl] Performance
From: "Michael Kay" <mhkay@xxxxxxxxxxxx>
Date: Thu, 13 Sep 2001 12:23:51 +0100
> Here are a few code snippets that might or might not be bad
> programming style but they're here for examples to open
> a discussion on tricks and performance...
> Making an indent or just creating an empty table element:
> <xsl:param name="mainindenthtml">
>   <img src="/wdp/images/spc.gif" height="1">
>     <xsl:attribute name="width"><xsl:value-of
> select='$bfora:mainindent'/></xsl:attribute>
>   </img>
> </xsl:param>

I would write that as
<img src="/wdp/images/spc.gif" height="1" width="{$bfora:mainindent}"/>
but that's not going to affect performance.

>       <xsl:choose>
>         <xsl:when test="number($bfora:mainindent)">
>           <TD width="{$bfora:mainindent}"><xsl:copy-of
> select="$mainindenthtml"/></TD>
>         </xsl:when>
>         <xsl:otherwise>
>           <TD />
>         </xsl:otherwise>
>       </xsl:choose>

Some processors might be marginally faster if mainindenthtml was a named
template rather than a global variable to be copied; but others might be
marginally slower. All would probably be a bit faster if you put the <img>
inline. It's unlikely to make a big difference.
> Calling sub templates to do things:
> <xsl:param name="tdgap"><td width="5"><img src="/wdp/images/spc.gif"
> width="5"/></td></xsl:param>
> 	<xsl:if test="number($itemshowkey1) or
> number($itemshownetworkicon1)">
> 		<TD>
> 			<xsl:attribute name="NOWRAP">1</xsl:attribute>

that seems a clumsy way of writing <TD NOWRAP="1">

> Loading up the keys:
>       <xsl:call-template name="bfora:subtext"/>
>       <xsl:variable name="keys" select="document($keyfile)"/>
>       <xsl:variable name="current" select="."/>
>       <xsl:for-each
> select="$keys/keyfile/keygroup[contains(concat(',',$keygroup,'
> ,'),concat(','
> ,id,','))]">
>         <xsl:copy-of
>           select="keyitem[word=$current/publickeyword or
>                           word=$current/adminkeyword or
>                           word=$current/group or
>                           word=$current/network]/itemhtml/*"/>
>       </xsl:for-each>

This raises a few red flags. How often is this code executed? How many
keygroups are there in $keyfile? How many of them match the contains()
predicate? Would it be worth defining an xsl:key so that they can be found
more quickly using key(xxx, $keygroup)?

In the <xsl:copy-of>, how many keyitem's are there in a keygroup? How many
of them match the predicate? How big are the node-sets "word" and
"$current/publickeyword" etc? Could an <xsl:key> help here?

> My text templates:
>   <xsl:template name="bfora:subtext">
>      <xsl:text disable-output-escaping="yes">
>       &lt;font face="verdana, arial" size="1" color="#000000"&gt;
>     </xsl:text>
>   </xsl:template>
>   <xsl:template name="bfora:subtext-end">
>     <xsl:text disable-output-escaping="yes">
>       &lt;/font&gt;
>     </xsl:text>
>   </xsl:template>

Yuk. Using disable-output-escaping to generate start and end tags as
separate operations is sheer laziness. It might not be a performance
problem, but it's bad programming all the same.

Mike Kay

 XSL-List info and archive:

Current Thread