Search code examples
xmlxsltoptimizationxslt-3.0accumulator

How can xsl:accumulator be used for some caching implementation inside of a xsl:function to speed up evaluation?


Before anything

Hi ! For industrial reasons, I am not able to provide real code examples, but I think my question is quite simple without it. I could train with "dummy" code, but it will take longer than necessary.By the way, take a look at this previous post of mine can give you a rough idea of ​​the input documents and my problem.

Context

I work on input xml documents whose "grammar" involves some "component/composite" kind of relationships with general idea is to declare entities like:

- "A is a component"
- "B is a composite using A"
- "C is a composite using B"
- "D is a composote using C"

Such relationship between entities "A, B" are carried by attribute with ID/IDREF constaints on them. The demo provided in this previous post of mine can be used to illustrate if you want.

Use case for XSL

XSL is used in that context with an already fully working transformation preforming "intensive criterion matching" among the input nodes and to produce a single output document that "summarizes" the results of those criterion evaluations on every relevant nodes.

  • because the nature of criterion to match involves traversing the mentioned relations between nodes, the search may involve recursivness so i implemented those criterion evaluation under functions, let say
<xsl:function name="my:criterion" ...>
  • so, for a given node A, it is possible that,during the walk of the tree, the criterion on A is evalutaed several times (but every criterion are determistic by nature !). When running, the transformatiom may result in a series of call as follows (pseudo code)
call my:criterion(A);
...
call my:criterion(B);
     | call my:criterion(A)
...
call my:criterion(C);
     |call my:criterion(B);
           | call my:criterion(A) 

call my:criterion(D);
     |call my:criterion(C);
           | call my:criterion(B)
                  | call my:criterion(A)

and so on ...

Problematic

Eventhough my transformation is already giving the expected results, I want some "deeper" understanding and better performance in terms of execution time. A way of otpimizing the transformation would be to implements some "result caching" while criterion are evaluated in order to avoid several evaluations on the same element (remember : the criterion functions are deterministic by nature) I thought xsl:accumulator could be of any help, but I just have discovered them, and I am not sure I can use them in the scope of a function.

Expectations

  • Thanks you for providing some hints on how to implement caching of function calls and how xsl:accumulator can / cannot be usefull in that purpose.

  • Thank you for not going too quickly in the "please provide some sample code" easy answering. I can think of "dummy" code to work with, but the time it takes to work on those dummy code is not worth if a quick answer can be obtained without them !


Solution

  • I think the feature you are looking for is

    <xsl:function ... cache="yes">
    

    This effectively turns the function into a "memo function" that remembers the results of previous invocations, and regurgitates them if the function is called repeatedly with the same arguments.

    For some restricted cases, xsl:accumulator could be used to achieve the same effect, but only (a) where it's a function of a single node, and (b) the function can be computed solely by reference to previous nodes in the same document. This is because xsl:accumulator is designed primarily to facilitate streaming.