Skip to content

perf(bigint): cache decimal division reciprocal - #4188

Merged
bobzhang merged 1 commit into
mainfrom
perf/bigint-to-string-reciprocal
Sep 2, 2026
Merged

bobzhang merged 1 commit into
mainfrom
perf/bigint-to-string-reciprocal

Conversation

@Yu-zh

@Yu-zh Yu-zh commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • cache the Möller–Granlund reciprocal for the decimal chunk divisor at module initialization
  • reuse the already-normalized 10^19 divisor with shift zero in every decimal conversion
  • preserve the 64-bit-limb formatter and its large-input scaling gains

Performance

Native release benchmark (moon bench bigint/to_string_bench_test.mbt --target native --release):

  • 40 digits: 205.14 ns before, 190.58 ns after
  • 400 digits: 1.38 µs after
  • 4000 digits: 88.51 µs after

Validation

  • moon check --deny-warn --target all
  • moon info --target wasm,wasm-gc,js,native (no .mbti changes)
  • moon fmt
  • moon test --target all
  • moon test --release --target all
  • moon bundle --all

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T06:30:25.402430Z c4ca463 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coveralls

coveralls commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 6498

Coverage remained the same at 90.976%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 3 of 3 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 18539
Covered Lines: 16866
Line Coverage: 90.98%
Coverage Strength: 283378.18 hits per line

💛 - Coveralls

@bobzhang
bobzhang force-pushed the perf/bigint-to-string-reciprocal branch from c4ca463 to a6bc339 Compare September 2, 2026 07:51
@bobzhang

bobzhang commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Perf sign-off ✅

Reviewed the change and verified it on this machine (absolute numbers differ from the PR's box, but the trend is what matters).

Correctness

  • Pure hoist, no behavior change: DECIMAL_CHUNK = 10^19 has its top bit set (10^19 > 2^63), so nlz(DECIMAL_CHUNK) == 0, dn == DECIMAL_CHUNK, and the cached reciprocal_word(DECIMAL_CHUNK) is exactly the value the old code recomputed once per to_string. The call div_w(..., DECIMAL_CHUNK, rec, 0) takes the identical s == 0 fast path.
  • moon check --deny-warn --target all
  • moon test bigint --target all (debug and --release) ✅ — 158 wasm / 188 wasm-gc / 162 js / 158 native, all passing
  • moon fmt --check bigint

Perfmoon bench bigint/to_string_bench_test.mbt --target <t> --release, 3 interleaved A/B rounds of base 4099af7 vs head a6bc339 (mean of 3 rounds):

target 40 digits 400 digits 4000 digits
native 186.1 → 159.8 ns (−14%) 1.33 → 1.29 µs (−3.5%) 85.2 → 89.1 µs (noise)
wasm-gc 183.0 → 179.7 ns (−1.8%) 3.47 → 3.51 µs (noise) 228.3 → 231.0 µs (noise)
js 75.1 → 73.7 ns (−1.8%) 2.27 → 2.28 µs (noise) 49.1 → 49.5 µs (noise)

The native win is exactly what the change predicts — one software reciprocal_word (synthesized 128/64 division) saved per conversion, a larger fraction for few-limb inputs and amortized to nothing at 4000 digits. wasm-gc/js are neutral within run-to-run noise, and there is no regression anywhere; the large-input scaling gains are preserved.

LGTM, thanks for the clean hoist 👍

@bobzhang
bobzhang merged commit 3082191 into main Sep 2, 2026
16 checks passed
@bobzhang
bobzhang deleted the perf/bigint-to-string-reciprocal branch September 2, 2026 08:16
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.

3 participants