Skip to content

perf(bigint): use 64-bit limbs on native and wasm - #4164

Merged
bobzhang merged 1 commit into
mainfrom
Yu-zh/bigint
Aug 31, 2026
Merged

perf(bigint): use 64-bit limbs on native and wasm#4164
bobzhang merged 1 commit into
mainfrom
Yu-zh/bigint

Conversation

@Yu-zh

@Yu-zh Yu-zh commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • use FixedArray[UInt64] limbs for BigInt on native and wasm1
  • retain the existing 32-bit limb implementation on wasm-gc to avoid the multi-value result regression
  • leave the JavaScript host-BigInt backend unchanged and preserve the generated public interface

Implementation

  • add full-width word/vector arithmetic, Karatsuba multiplication, reciprocal and Knuth division, and Montgomery exponentiation
  • lower %u64.mul_wide on native while keeping a portable wasm1 fallback that can adopt wide arithmetic later
  • select implementations and white-box tests with file-based target conditions
  • make deprecated hexadecimal helpers representation-independent
  • cover the UInt64 Karatsuba transition at 63, 64, and 65 limbs

Testing

  • moon check bigint --target all --deny-warn
  • moon test bigint --target all --release
  • moon test --target all
  • moon test --release --target js,wasm,wasm-gc
  • moon test --target native --release
  • moon info --target wasm,wasm-gc,js,native with no .mbti diff
  • moon bundle --all

@coveralls

coveralls commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 6424

Coverage decreased (-0.02%) to 90.912%

Details

  • Coverage decreased (-0.02%) from the base build.
  • Patch coverage: 16 uncovered changes across 2 files (541 of 557 lines covered, 97.13%).
  • 1 coverage regression across 1 file.

Uncovered Changes

File Changed Covered %
bigint/bigint_wide.mbt 434 422 97.24%
bigint/arith_wide.mbt 123 119 96.75%

Coverage Regressions

1 previously-covered line in 1 file lost coverage.

File Lines Losing Coverage Coverage
debug/pretty_print.mbt 1 91.74%

Coverage Stats

Coverage Status
Relevant Lines: 18551
Covered Lines: 16865
Line Coverage: 90.91%
Coverage Strength: 283694.91 hits per line

💛 - Coveralls

@Yu-zh
Yu-zh marked this pull request as draft August 28, 2026 02:55

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac4ed6d8d5

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bigint/moon.pkg Outdated
Comment thread bigint/bigint_wide_wbtest.mbt Outdated
@Yu-zh
Yu-zh force-pushed the Yu-zh/bigint branch 5 times, most recently from 33fbd26 to a876bfe Compare August 31, 2026 03:28
@Yu-zh
Yu-zh marked this pull request as ready for review August 31, 2026 03:34
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 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-08-31T03:44:13.699132Z a876bfe Draft marked ready
ℹ️ 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.

Keep wasm-gc on the existing 32-bit limb implementation because wide arithmetic multi-value results regress there.
@bobzhang
bobzhang enabled auto-merge (squash) August 31, 2026 07:05
@bobzhang
bobzhang merged commit ee6421b into main Aug 31, 2026
16 checks passed
@bobzhang
bobzhang deleted the Yu-zh/bigint branch August 31, 2026 07:10
CAIMEOX added a commit that referenced this pull request Aug 31, 2026
* Handle minimum signed values in QuickCheck shrinking

* Assert complete minimum-value shrink sequences

* docs(builtin): expand documentation for integer min/max/clamp

`Int64::min`, `Int64::max`, `Int64::clamp`, `UInt::min`, `UInt::max` and
`UInt::clamp` carried one-line comments while their documented siblings
follow the full structure. Bring all six to the same level: semantics,
parameters, return behavior (including the abort when `min > max` in
`clamp`) and executable examples.

Continues #623

* chore: remove deprecated APIs

* perf(bytes): skip redundant initialization in concatenation (#4142)

* perf(bytes): skip redundant initialization in concatenation

* Limit Bytes benchmark setup to benchmark runs

* refactor(bigint): read each from_octets limb with a u32be pattern (#4099)

* refactor(bigint): read each limb with a u32be pattern in from_octets

The inner loop was a 4-iteration big-endian shift-accumulate, which is
exactly one u32be read (RADIX_BIT_LEN = 32).

Measured: native -34% at n=1024 / -24% at n=64, wasm-gc -46% / -42%.
js is unaffected (bigint_js.mbt has its own from_octets).

* bench(bigint): add from_octets benchmarks

Covers the limb-fill path at n=64 and n=1024 so the u32be conversion in
the previous commit is reproducible.

Signed-off-by: Codex CLI <codex@openai.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(bigint): pin RADIX_BIT_LEN so the u32be limb read can't drift

Addresses the review note that `from_octets`'s tail now hard-codes a
32-bit read while `byte_per_limb` is still derived from `RADIX_BIT_LEN`.

Rather than branch on the constant at runtime, the assumption is pinned
by a whitebox test and named in the comment above the loop: narrowing
`RADIX_BIT_LEN` now fails a test instead of silently mis-decoding.

The pin uses `@test.assert_eq`, not `inspect`. A snapshot would be
rewritten by `moon test --update`, which would retire the guard at
exactly the moment it is supposed to fire; `assert_eq` is not
auto-updatable. Verified both halves by temporarily setting the expected
value to 16: the test fails with `32 != 16`, and `moon test --update`
leaves it failing rather than rewriting it.

A runtime fallback was considered and rejected. Restoring the old
shift-accumulate loop as the "generic" arm would not actually be generic:
`byte_per_limb` is `RADIX_BIT_LEN / 8`, so for the documented-legal
widths 4, 12, 20 and 28 (the file only requires a multiple of 4, at most
32) that loop truncates and mis-decodes just as badly. It would trade a
loud failure for a quiet one, plus a permanently dead branch that no test
can reach.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Codex CLI <codex@openai.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: improve scalar Arbitrary

* use integer literal suffix or constructor

* fix: improve test strength

* refactor: uniform Byte generation

* adjust shrinking order of 0

* perf(bigint): use 64-bit limbs on native and wasm (#4164)

Keep wasm-gc on the existing 32-bit limb implementation because wide arithmetic multi-value results regress there.

---------

Signed-off-by: Codex CLI <codex@openai.com>
Co-authored-by: Li Fengmin <2080291162@qq.com>
Co-authored-by: Yu Zhang <yu.zhang.yz862@yale.edu>
Co-authored-by: Hongbo Zhang <bobzhang1988@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: CAIMEO <38813005+CAIMEOX@users.noreply.github.com>
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