Skip to content

perf: Speed up addition time for drastically different exponents - #7825

Open
ximinez wants to merge 14 commits into
developfrom
ximinez/number-exponents
Open

perf: Speed up addition time for drastically different exponents#7825
ximinez wants to merge 14 commits into
developfrom
ximinez/number-exponents

Conversation

@ximinez

@ximinez ximinez commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

High Level Overview of Change

  • When dropping digits, short circuit the loop if the smaller value loses all significant digits in both the mantissa, and the Guard.
  • Adds unit tests demonstrating some extreme examples.

Context of Change

We received a report that a Json string with an out of range exponent (e.g. 1e2000000000) would successfully bypass Number invariants, and that adding anything to that value would tie up the node for 1-2 seconds as the exponents were brought into sync. The report was completely wrong about the Json parsing. (I added tests to STNumber_test.cpp demonstrating such.) Those values overflow as designed and expected.

However, when I checked two numbers with exponents at the valid opposite extremes (e.g. approximately 1e32767 and 1e-32767), there was in fact a measurable delay.

Before tests, the entire Number test suite took < 1ms (the granularity at which the test harness measured).

I added 16 addition operation tests of such Numbers (one for each combination of MantissaScale and RoundingMode). Together, they took about 80ms. So an average of about 5ms each. Still a pretty insignificant amount of time. Additionally, because the STAmounts, which every STNumber field actually represents, have an exponent range of -96 to 80, any of these extreme values will not get very far in the transaction engine itself. Thus I conclude that the current behavior is not exploitable in any meaningful way. A 5ms addition operation is likely to be dwarfed by the I/O of loading the necessary ledger object for any transaction in which it is relevant.

The fix is relatively straightforward: When shrinking the mantissa and increasing the exponent of one of the operands in an addition operation, if that operand reaches a state where the only possible change would be to increase the exponent, simply set that exponent to the exponent of the other (larger) operand, and exit the loop. The fact that digits were dropped is still preserved, so when rounding up, the result still rounds up to the next representable value.

With this fix, the entire Number test suite is back to running in under 1ms.

ximinez added 4 commits July 15, 2026 18:45
- When dropping digits, short circuit the loop if the smaller value
  loses all significant digits in both the mantissa, and the Guard.
- Adds unit tests demonstrating some extreme examples.

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a performance corner case in xrpl::Number addition when operands have exponents at opposite extremes of the valid range, avoiding long digit-dropping loops when the smaller operand has no remaining significant/recoverable digits. It also adds tests to demonstrate both the performance-sensitive addition scenario and expected overflow behavior when parsing extremely large exponents from JSON.

Changes:

  • Add a Number::Guard fast-path (doDropDigitWithTarget) to jump the exponent to the target once the mantissa is zero and guard digits are no longer recoverable.
  • Add unit tests covering addition with kMaxExponent vs kMinExponent across rounding modes.
  • Add unit tests asserting JSON parsing/normalization overflows for very large exponent strings (e.g. 1e2000000000).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/libxrpl/basics/Number.cpp Adds a guard-based short-circuit during exponent alignment in addition to avoid pathological loop counts.
src/tests/libxrpl/basics/Number.cpp Adds regression tests for extreme-exponent addition behavior (including rounding-mode-specific expectations) and a normalization overflow case.
src/test/protocol/STNumber_test.cpp Refactors repeated exception assertions into a helper and adds overflow tests for huge exponent strings passed via JSON.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good.

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Solid logic with thorough testing. Good to ship.

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