RE: [xsl] performance with template and choose

Subject: RE: [xsl] performance with template and choose
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Thu, 12 Sep 2002 09:29:55 +0100
It looks as if MSXML3 isn't clever enough to spot that the different
match patterns contain common subexpressions (e.g.

KH[@Type='401']/Key[@ProdID ='83' and translate(@StopVal, '-','')
&lt;='20050911']

and so it is evaluating this subexpression several times for each
candidate node. Your rewritten code avoids this by factoring out the
subexpression so that there is a two-stage test.

Saxon won't do this optimization either, though in 7.2 I've started to
put the logic in place to factor out common subexpressions.
Interestingly, in Saxon 7.2 you could do this yourself with a memo
function:

<xsl:template match="MD[z:type-1(.) and @ACPID='100']/@AAvl"
> priority="1001" >


<xsl:function name="z:type-1" saxon:memo-function="yes">
  <xsl:param name="N"/>
  <xsl:return select=boolean($N/parent::Key[@ProdID ='83' and
translate(@StopVal, '-','') &lt;='20050911']/parent::KH[@Type='401'])"/>
</xsl:function>

If a memo function is called twice with the same arguments, it remembers
the result from the first time and avoids re-evaluating the function.

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 


> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> Kimberly Hahn
> Sent: 11 September 2002 22:20
> To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] performance with template and choose
> 
> 
> 
> I have a transformation that takes roughly 2.8 sec to run 
> (using MSXML).  I
> made some changes to it, moving some of the template matches 
> into a choose
> within a broader template.  This change was made for 
> functional reasons, but
> it cut the transformation time down to 1.4 sec.  I was just curious if
> someone could shed light on why there was the performance improvement.
> 
> Sample differences:
> slower version was structured as -
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20050911']/MD[@ACPID='100']/@AAvl"
> priority="1001" >
> <xsl:attribute name="AAvl">1</xsl:attribute>
> </xsl:template>
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20050911']/MD[@BCPID='100']/@BAvl"
> priority="1002" >
> <xsl:attribute name="BAvl">1</xsl:attribute>
> </xsl:template>
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20030911']/MD[@ACPID='10']/@AAvl"
> priority="1003" >
> <xsl:attribute name="AAvl">1</xsl:attribute>
> </xsl:template>
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20030911']/MD[@BCPID='10']/@BAvl"
> priority="1004" >
> <xsl:attribute name="BAvl">1</xsl:attribute>
> </xsl:template>
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20030311']/MD[@ACPID='3']/@AAvl"
> priority="1005" >
> <xsl:attribute name="AAvl">1</xsl:attribute>
> </xsl:template>
> <xsl:template match="KH[@Type='401']/Key[@ProdID ='83' and
> translate(@StopVal, '-','') &lt;='20030311']/MD[@BCPID='3']/@BAvl"
> priority="1006" >
> <xsl:attribute name="BAvl">1</xsl:attribute>
> </xsl:template>
> 
> faster version as -
> <xsl:template match="KH/Key[@ProdID ='83']/MD/@AAvl" priority="1001">
> <xsl:attribute name="AAvl">
> <xsl:choose>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20030311'
> and (parent::MD/@ACPID='3')">1</xsl:when>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20030911'
> and (parent::MD/@ACPID='10')">1</xsl:when>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20050911'
> and (parent::MD/@ACPID='100')">1</xsl:when>
> </xsl:choose>
> </xsl:attribute>
> </xsl:template>
> <xsl:template match="KH/Key[@ProdID ='83']/MD/@BAvl" priority="1001">
> <xsl:attribute name="BAvl">
> <xsl:choose>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20030311'
> and (parent::MD/@BCPID='3')">1</xsl:when>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20030911'
> and (parent::MD/@BCPID='10')">1</xsl:when>
> <xsl:when test="translate(ancestor::Key/@StopVal, '-','') 
> &lt;='20050911'
> and (parent::MD/@BCPID='100')">1</xsl:when>
> </xsl:choose>
> </xsl:attribute>
> </xsl:template>
> 
> All other things (other named templates and unrelated 
> template matches) in
> the XSL documents were unchanged.
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread