The Saxon-SA optimizer causes certain filter expressions to be evaluated using indexing. There have been some changes in the strategy in this release.

There are essentially two kinds of index used: document-level indexes, and variable-level indexes. Document-level indexes are used when the expression being filtered is a path expression rooted at a document node; in this case the index (like an xsl:key index in XSLT) is attached to the document node, and lives as long as the document itself lives. Variable-level indexes are used when the expression being filtered is represented by a variable reference, which may be because it is written in the source as a variable reference, or because it is an expression that Saxon has moved out of a containing loop, thus creating a synthetic variable.

For document-level indexes:

Variable-level indexes:

Other optimization changes

In previous releases a path expression was not optimized (and therefore never used an index) if the last step returned an atomic value rather than a node. This omission has been rectified.

Saxon now performs variable inlining where appropriate. If a variable is referenced only once, and the reference is not within any kind of loop, then the expression to which the variable is bound is substituted for the variable reference. This avoids the need to create run-time closures in such cases.

Where the specification of a system function states that "if the value of argument N is an empty sequence, the result is X" (regardless of the values of any other arguments), and when argument N is known at compile time to be an empty sequence, then the call to the system function is replaced by X at optimization time.