Skip to content

A few performance improvements - #6515

Merged
kit-ty-kate merged 5 commits into
ocaml:masterfrom
dra27:easy-wins
Nov 28, 2025
Merged

A few performance improvements#6515
kit-ty-kate merged 5 commits into
ocaml:masterfrom
dra27:easy-wins

Conversation

@dra27

@dra27 dra27 commented May 10, 2025

Copy link
Copy Markdown
Member

Our version comparison function is very hot. While looking around it in the context of #4245, I picked up on a few easy wins. These are some basic results from hyperfine on my system for opam show dune, but they must be taken with an appropriate amount of salt:

OCaml 5.4.0
Base:    902.6 ms ±  32.7 ms
ramp_up: 553.4 ms ±  48.5 ms
closure: 539.6 ms ±  26.9 ms
files:   378.0 ms ±  14.5 ms

OCaml 5.3.0
Base:    913.2 ms ±  46.4 ms
ramp_up: 878.5 ms ±  36.5 ms
closure: 866.5 ms ±  34.7 ms
files:   756.4 ms ±  38.7 ms

OCaml 4.14.2
Base:    1.090 s ±  0.030 s
ramp_up: 1.114 s ±  0.053 s
closure: 1.108 s ±  0.059 s
files:   842.2 ms ±  26.9 ms

The interesting part is that on OCaml 5.4, opam show spends almost its entire time unmarshalling the repository state cache. However, these changes shouldn't be assessed in terms of performance improvement because what's happening on all versions of OCaml is a reduction in GC pressure (i.e. if opam were doing a bit more work, the GC would almost certainly run again and the time reduction wouldn't be as stark). The three changes are:

  • Use OCaml 5.4's Gc.ramp_up for the unmarshalling call in OpamCached. This is logically sensible, as the caches are never collected. The speedup comes from the fact that the major GC doesn't actually have to run any more in the opam show command, and the 5.3.0 and 4.14.2 results for that commit are well within the noise of the microbenchmark.
  • OpamStd.String.compare_case added in Optimise package name comparison #4328 contained a small mistake - the closure allocation for the aux function shows up in flame graphs. The derivation of sets of packages from the map of opams in OpamRepositoryState (which is also done in OpamSwitchState) is mostly dominated by OpamVersionCompare, but eliminating the closure in compare_case has a benefit (as it happens, I also got a small benefit from a Hacker's Delight-style optimisation noting that opam package names can't contain certain characters, but as the function is also used for system package names, I decided not to commit that one!). The diff looks noisy without space-change being ignored - all I've done is move the aux function out of compare_case.
  • Finally, I noticed with opam show dune that the switch selections of the switches are read in proportion to the number of versions being displayed. That creates both unnecessary I/O and GC pressure. extracted in opam show: Reduce I/O when multiple versions of a package exist #6818

I think all three of these changes are worth putting in, but I'd countenance against hyping the performance improvement on opam show because it won't always show up that way!

Comment thread src/core/opamVersionCompare.ml
@kit-ty-kate
kit-ty-kate force-pushed the easy-wins branch 2 times, most recently from eab0cef to 9fdc865 Compare October 13, 2025 19:43
Comment thread src/core/opamVersionCompare.ml Outdated

@rjbou rjbou left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rebased the PR, extracted opam show improvement in its own PR (to keep this PR for core changes), and split commits that concerns functions additions.
LGTM!

@kit-ty-kate

Copy link
Copy Markdown
Member

Thanks a lot!

@kit-ty-kate
kit-ty-kate merged commit 4014b58 into ocaml:master Nov 28, 2025
46 checks passed
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.

3 participants