Skip to content

Optimize comparison of parsed versions - #15748

Merged
ericmj merged 2 commits into
mainfrom
optimize-version-compare
Aug 14, 2026
Merged

Optimize comparison of parsed versions#15748
ericmj merged 2 commits into
mainfrom
optimize-version-compare

Conversation

@ericmj

@ericmj ericmj commented Aug 14, 2026

Copy link
Copy Markdown
Member

Version.compare/2 converted parsed %Version{} values into two five-element tuples before comparing them. This adds a struct-to-struct clause that passes the precedence fields directly to the comparator, avoiding both tuple allocations. String and mixed operands retain parsing and validation through to_matchable/2, then call the same field comparator. Build metadata remains ignored.

Benchmarks used Elixir 1.21.0-dev, Erlang/OTP 29, macOS arm64, and one scheduler (+S 1:1). The benchmark baseline was bc7844c. Five runs produced 500 batch-average samples for individual comparisons and 150 complete-operation samples across six shuffled, one ascending, and one descending input order.

Timed boundary Baseline median / p99 Updated median / p99 Median speedup
Early-core comparison 34.06 / 47.14 ns 19.40 / 24.44 ns 1.76x
Numeric-prerelease comparison 49.77 / 60.15 ns 32.65 / 40.10 ns 1.52x
Long-alphanumeric comparison 45.92 / 55.23 ns 29.61 / 35.01 ns 1.55x
Build-only difference 55.18 / 76.30 ns 39.38 / 46.36 ns 1.40x
1,000-digit core comparison 54.26 / 63.74 ns 37.85 / 44.28 ns 1.43x
Sort 895 parsed versions 369.50 / 589.58 us 258.25 / 404.08 us 1.43x
Sort 2,964 parsed versions 1.373 / 2.463 ms 1.019 / 1.217 ms 1.35x
Select maximum from 895 parsed versions 34.88 / 77.42 us 27.79 / 80.00 us 1.26x
Select maximum from 2,964 parsed versions 102.29 / 189.00 us 77.67 / 137.88 us 1.32x

Parsed sorting and maximum selection exclude parsing. Parsing strings once and then sorting improved by 1.09x at 895 versions and 1.06x at 2,964 versions, although the per-run median ranges overlapped. Sorting strings through the public comparator remained within run variation.

OTP tprof allocation profiling measured 12 heap words, or 96 bytes on this VM, per baseline parsed comparison and zero words after the change. The semantic oracle compared 38,416 ordered pairs, including arbitrary-size core and prerelease integers, mixed and prefix prerelease lists, stable releases, build ties, and long identifiers, with no mismatches.

make format and make test_stdlib TEST_FILES=version_test.exs pass with 43 tests.

@ericmj
ericmj marked this pull request as ready for review August 14, 2026 14:06
@ericmj
ericmj merged commit a357d19 into main Aug 14, 2026
26 checks passed
@ericmj
ericmj deleted the optimize-version-compare branch August 14, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants