Skip to content

perf: compare same-type numbers without going through BigDecimal - #1299

Merged
anidotnet merged 1 commit into
nitrite:mainfrom
brettwooldridge:fix/numbers-compare-fast-path
Sep 4, 2026
Merged

perf: compare same-type numbers without going through BigDecimal#1299
anidotnet merged 1 commit into
nitrite:mainfrom
brettwooldridge:fix/numbers-compare-fast-path

Conversation

@brettwooldridge

Copy link
Copy Markdown
Contributor

Numbers.compare converted both operands to BigDecimal on every call, two allocations per comparison, and every index key comparison lands there. On a production (!) store with numeric index keys the conversion was the hottest frame in a multi-hour index rebuild.

The common cases are now answered directly and exactly: any two integral primitives compare as longs, two doubles or two floats compare as themselves once NaN and the infinities have taken the existing special-case path, with -0.0 and 0.0 equal as BigDecimal treats them, and two BigDecimals or two BigIntegers use their own compareTo. Every mixed pairing keeps the exact BigDecimal conversion, so cross-type equality such as Integer 1 against Float 1.0f is unchanged.

The parameterized test gains the long extremes, integral mixes, signed zeros, NaN ordering, a float widened against a double, and mixed pairs that must still take the exact path.

Numbers.compare converted both operands to BigDecimal on every call, two
allocations per comparison, and every index key comparison lands there.
On a store with numeric index keys the conversion was the hottest frame in
a multi-hour index rebuild.

The common cases are now answered directly and exactly: any two integral
primitives compare as longs, two doubles or two floats compare as
themselves once NaN and the infinities have taken the existing special-case
path, with -0.0 and 0.0 equal as BigDecimal treats them, and two
BigDecimals or two BigIntegers use their own compareTo. Every mixed pairing
keeps the exact BigDecimal conversion, so cross-type equality such as
Integer 1 against Float 1.0f is unchanged.

The parameterized test gains the long extremes, integral mixes, signed
zeros, NaN ordering, a float widened against a double, and mixed pairs
that must still take the exact path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 52 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 53854fdc-9496-49c0-85f4-475230d2d1c2

📥 Commits

Reviewing files that changed from the base of the PR and between 38caf34 and 65650cf.

📒 Files selected for processing (2)
  • nitrite/src/main/java/org/dizitart/no2/common/util/Numbers.java
  • nitrite/src/test/java/org/dizitart/no2/common/util/NumbersTest.java

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@anidotnet
anidotnet merged commit a01e120 into nitrite:main Sep 4, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants