Bug #5925


Performance: dynamic function lookup runs very slowly under Saxon-JS

Added by Mary Holstege over 1 year ago. Updated 8 months ago.

Start date:
Due date:
% Done:


Estimated time:
Applies to JS Branch:
2, Trunk
Fix Committed on JS Branch:
2, Trunk
Fixed in JS Release:
SEF Generated with:
Contact person:
Additional contact persons:


This is a strange performance issue.

I have tried to boil this down, but when I do so, the performance problem evaporates so I'm afraid there is a huge wodge of code here, for which I apologize.

When I run this stylesheet in XSLT, it runs in a few seconds. This is a direct translation of some XQuery code, which also runs in seconds. In node (or a browser), however it takes over a minute. If I run the full set of tests it takes 11 hours to run instead of half a minute.

I ran some basic profiling: it seems to be killing itself with GC if I'm reading this right. (see profile20230317.txt)

The script is how I'm running this; obviously all the paths and whatnot would need fixing. It is Saxon 12.0 to do the export to JSON and then xslt3.js to run it.

Saxon-JS 2.5, Saxon 12.0

Files (251 KB) Zip file of code Mary Holstege, 2023-03-17 17:56
profile20230317.txt (16.8 KB) profile20230317.txt Profile Mary Holstege, 2023-03-17 18:01
Actions #1

Updated by Norm Tovey-Walsh over 1 year ago

Thanks, Mary. I'll try to look at this next week.

Actions #2

Updated by Michael Kay over 1 year ago

John Lumley points out that the example makes extensive use of packages. We may need to take a look at the SaxonJS code for binding cross-package component references (such as function calls), which has probably not been stress-tested.

Actions #3

Updated by Norm Tovey-Walsh about 1 year ago

  • Status changed from New to Resolved
  • Applies to JS Branch Trunk added
  • Fix Committed on JS Branch Trunk added

A quick review of the profile pointed me to the code for dynamic function lookup. The test case does more than 600 lookups but only actually calls 5 functions. So we were doing ~595 unnecessary lookups. That's a linear search (I think) through all of the possible functions. Rather than trying to make a more complex data structure, I simply added a cache. The test case is now 13x faster and finishes easily in a couple of seconds.

The patch didn't apply cleanly to the saxonjs2 branch so I haven't ported it. If we end up doing another Saxon2 release, we should.

Actions #4

Updated by Michael Kay 9 months ago

  • Subject changed from Performance: XSL runs very slowly under Saxon-JS to Performance: dynamic function lookup runs very slowly under Saxon-JS
Actions #5

Updated by Norm Tovey-Walsh 9 months ago

  • Fix Committed on JS Branch 2 added

Patch applied to the saxonjs2 branch

Actions #6

Updated by Debbie Lockett 8 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in JS Release set to SaxonJS 2.6

Bug fix applied in the SaxonJS 2.6 maintenance release.

Please register to edit this issue

Also available in: Atom PDF Tracking page