Performance: call-template vs apply-template


in XSLT processing, is there a performance difference between apply-template and call-template? In my stylesheets there are many instances where I can use either, which is the best choice?

Best Solution

As with all performance questions, the answer will depend on your particular configuration (in particular the XSLT processor you're using) and the kind of processing that you're doing.

<xsl:apply-templates> takes a sequence of nodes and goes through them one by one. For each, it locates the template with the highest priority that matches the node, and invokes it. So <xsl:apply-templates> is like a <xsl:for-each> with an <xsl:choose> inside, but more modular.

In contrast, <xsl:call-template> invokes a template by name. There's no change to the context node (no <xsl:for-each>) and no choice about which template to use.

So with exactly the same circumstances, you might imagine that <xsl:call-template> will be faster because it's doing less work. But if you're in a situation where either <xsl:apply-templates> or <xsl:call-template> could be used, you're probably going to be doing the <xsl:for-each> and <xsl:choose> yourself, in XSLT, rather than the processor doing it for you, behind the scenes. So in the end my guess it that it will probably balance out. But as I say it depends a lot on the kind of optimisation your processor has put into place and exactly what processing you're doing. Measure it and see.

My rules of thumb about when to use matching templates and when to use named templates are:

  • use <xsl:apply-templates> and matching templates if you're processing individual nodes to create a result; use modes if a particular node needs to be processed in several different ways (such as in the table of contents vs the body of a document)
  • use <xsl:call-template> and a named template if you're processing something other than an individual node, such as strings or numbers or sets of nodes
  • (in XSLT 2.0) use <xsl:function> if you're returning an atomic value or an existing node
Related Question