Subject: Re: [xsl] Regarding XSL performance on AIX From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 17 May 2002 10:21:38 +0100 |
Hi Anand, > In a similar fashion by calling nested templates, I transform the > XSL to display the XML as a collapsible tree. When I do the > transformation on WindowsNT it takes 20/25 seconds wheres on AIX it > takes 3/4 minutes. I just can figure out why? Does any one have any > idea why this happens? Please tell me how I can fine tune my XSL for > enhanced performance. The thing that's probably slowing your stylesheet down massively is the fact that you've got a load of paths that are using the descendant axis. You're also using absolute paths where I think you mean to use relative paths, which I think means that your stylesheet will be giving you unexpected results as well as being very slow. If you do want to use absolute paths, e.g.: //NODE2 which collects all the NODE2 elements in the document, then you should create global variables to hold the results of using them, rather than calculating them afresh each time you encounter a NODE1 element. If you want to collect information relative to a particular node, then your path shouldn't start with a /. Take all the paths that you're using in your NODE1 template: <!-- Check if this Node has Children --> <xsl:variable name = "countofNode2"> <xsl:value-of select = "count(//NODE2)"/> </xsl:variable> <!-- Set the Variables like NodeAddress,levelidentifier,Nodename to be passed to javascript functions --> <xsl:variable name = "nodeaddr1"> <xsl:value-of select = "(//NODE1/NODEADDRESS) "/> </xsl:variable> <xsl:variable name = "lidentifier1"> <xsl:value-of select = "(//NODE1/LEVELIDENTIFIER) "/> </xsl:variable> <xsl:variable name = "nodename1"> <xsl:value-of select = "(//NODE1/NODENAME) "/> </xsl:variable> <xsl:variable name = "color1"> <xsl:value-of select = "(//NODE1/ISGREY) "/> </xsl:variable> I think all these should be relative. <!-- Check if this Node has Children --> <xsl:variable name = "countofNode2"> <xsl:value-of select = "count(NODE2)"/> </xsl:variable> <!-- Set the Variables like NodeAddress,levelidentifier,Nodename to be passed to javascript functions --> <xsl:variable name = "nodeaddr1"> <xsl:value-of select = "NODEADDRESS"/> </xsl:variable> <xsl:variable name = "lidentifier1"> <xsl:value-of select = "LEVELIDENTIFIER"/> </xsl:variable> <xsl:variable name = "nodename1"> <xsl:value-of select = "NODENAME"/> </xsl:variable> <xsl:variable name = "color1"> <xsl:value-of select = "ISGREY"/> </xsl:variable> You should also be using the select attribute of xsl:variable, since otherwise you get the processor to create result tree fragments, which are relatively expensive to create compared to variables containing pointers to nodes or values: <!-- Check if this Node has Children --> <xsl:variable name = "countofNode2" select="count(NODE2)" /> <!-- Set the Variables like NodeAddress,levelidentifier,Nodename to be passed to javascript functions --> <xsl:variable name = "nodeaddr1" select="NODEADDRESS" /> <xsl:variable name = "lidentifier1" select="LEVELIDENTIFIER" /> <xsl:variable name = "nodename1" select="NODENAME" /> <xsl:variable name = "color1" select="ISGREY" /> As a general rule, you should also try to use a step-by-step path down to the nodes that you're interested in. So given that NODE2 elements can only occur within a NODE1 element, which is the document element, you should use: /NODE1/NODE2 This saves the processor a massive amount of work. Rather than having to search through the entire document (including all the contents of all those NODE4 elements), it can just look at the children of the NODE1 element to try to find the NODE2 element that it's after. You seem to be using the count of NODE2 elements as a way of testing whether there are any NODE2 elements. That's a bad idea. You can tell whether there are any NODE2 elements just by finding one NODE2 element. On the other hand, to count NODE2 elements, you have to go all the way through the children of NODE1 to gather them all together. So it will save you some time if you don't bother counting them, just try seeing if there's one of them: <!-- Check if this Node has Children --> <xsl:variable name = "node2child" select="NODE2[1]" /> and then use xsl:choose rather than two xsl:ifs that cannot both be true -- that means you only do the test once: <xsl:choose> <xsl:when test="$node2child"> ... there are NODE2 children ... </xsl:when> <xsl:otherwise> ... there aren't NODE2 children ... </xsl:otherwise> </xsl:choose> As Mike B.'s already pointed out, implementing loops using counters is not going to be very efficient in XSLT. It's a much better idea to apply templates to the NODE2 elements in order to process them, or use xsl:for-each: <xsl:for-each select="NODE2"> ... do stuff with the NODE2 elements ... </xsl:for-each> Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Regarding XSL performance, Mike Brown | Thread | RE: [xsl] Regarding XSL performance, Michael Kay |
Re: [xsl] template precedence probl, Jeni Tennison | Date | Re: [xsl] xsl:value-of not allowed , Jeni Tennison |
Month |