Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: use libxml2 patch for faster xpath context init #3389

Merged

Conversation

flavorjones
Copy link
Member

What problem is this PR intended to solve?

After chatting with @nwellnhof in #3378, he went ahead and made an performance-focused change upstream in libxml2/gnome@bf5fcf6e that I'm pulling in here to the vendored library.

Benchmark comparing this PR against v1.17.x ("main"):

Comparison:
         large: main:     3910.6 i/s
      large: patched:     3759.6 i/s - same-ish: difference falls within error

Comparison:
      small: patched:   242901.7 i/s
         small: main:   127486.0 i/s - 1.91x  slower

We could get greater performance gains by re-using XPathContext objects, but only at the cost of a significant amount of additional complexity, since in order to properly support recursive XPath evaluation, Nokogiri would have to push and pop "stack frames" containing:

  • internal state contextSize and proximityPosition
  • registered namespaces
  • registered variables
  • function lookup handler

That feels like a lot of code for a small win.

Comparatively, pulling in this upstream patch is still a ~2x speedup with zero additional complexity. That's a win.

Have you included adequate test coverage?

N/A

Does this change affect the behavior of either the C or the Java implementations?

Performance improvement impacting CRuby only.

Revert the pieces of 969bea9 related to re-use of xpath context
objects.

Leave in these pieces of that commit:

- ability to de-register variables and namespaces
- XPathContext#node=

and backfill explicit test coverage for these features.
See extended discussion at #3378

Benchmark comparing this commit against v1.17.x ("main"):

  Comparison:
           large: main:     3910.6 i/s
        large: patched:     3759.6 i/s - same-ish: difference falls within error

  Comparison:
        small: patched:   242901.7 i/s
           small: main:   127486.0 i/s - 1.91x  slower

I think we could get greater performance gains by re-using
XPathContext objects, but only at the cost of a significant amount of
additional complexity, since in order to properly support recursive
XPath evaluation, Nokogiri would have to push and pop "stack frames"
containing:

- internal state contextSize and proximityPosition
- registered namespaces
- registered variables
- function lookup handler

That feels like a lot of code for a small win. Comparatively, pulling
in this upstream patch is still a 2x speedup for zero additional complexity.
@flavorjones flavorjones force-pushed the flavorjones-use-libxml2-patch-for-faster-xpath-context-init branch from fcc4298 to 3f20dd9 Compare December 21, 2024 20:07
@flavorjones flavorjones added this to the v1.18.0 milestone Dec 21, 2024
@flavorjones flavorjones changed the title pef: use libxml2 patch for faster xpath context init perf: use libxml2 patch for faster xpath context init Dec 21, 2024
@flavorjones flavorjones disabled auto-merge December 21, 2024 22:13
@flavorjones flavorjones merged commit 0892e03 into main Dec 21, 2024
142 of 145 checks passed
@flavorjones flavorjones deleted the flavorjones-use-libxml2-patch-for-faster-xpath-context-init branch December 21, 2024 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant