Skip to content

perf: route safeDiv through divLimbsDirect (not the builtin u256 /)#107

Merged
koko1123 merged 1 commit into
mainfrom
koko/uint256-safediv-fast-path
Jul 15, 2026
Merged

perf: route safeDiv through divLimbsDirect (not the builtin u256 /)#107
koko1123 merged 1 commit into
mainfrom
koko/uint256-safediv-fast-path

Conversation

@koko1123

@koko1123 koko1123 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What

uint256.safeDiv was return a / b; — the builtin u256 division, which lowers to a slow software long-division on aarch64 (measured ~330 ns for a 256/128-bit divide). This routes it through the limb-based divLimbsDirect the library already ships and that mulDiv / the dex math already use (Knuth Algorithm D over [4]u64 with div128by64 = 2 hardware UDIVs).

Why it matters

safeDiv is the public division helper, so every caller silently paid the slow path while the fast implementation sat one call away. Found while chasing a Uniswap TickMath hotspot in a downstream SDK: the positive-tick maxInt/ratio divide dominated the function, and swapping the builtin / for divLimbsDirect was a ~3× win on that op alone (and ~6.5× on the whole function combined with limb multiply).

Safety

No behavior change — divLimbsDirect returns the same quotient as / (it's already the tested primitive behind mulDiv). The full suite passes: 856/856, including the safeDiv and divLimbsDirect cases. zig fmt --check clean.

Follow-up (not in this PR)

The internal divLimbs (used nowhere on the public path now) still calls knuthDivCore directly, skipping divLimbsDirect's 2-limb register fast path. Worth aligning if it gains callers.

Summary by CodeRabbit

  • Bug Fixes
    • Improved large-integer division reliability and performance.
    • Division by zero continues to be handled safely without errors.

safeDiv fell back to the builtin u256 '/', which lowers to a slow software
long-division on aarch64 (~330ns for a 256/128-bit divide). The library
already ships the fast limb path -- divLimbsDirect (Knuth D over [4]u64 with
div128by64 = 2 hardware UDIVs), used by mulDiv and the dex math. Route
safeDiv through it so every caller of the public division helper gets the
fast path (tens of ns).

No behavior change: divLimbsDirect returns the same quotient as '/'. Full
suite passes (856 tests) incl. the safeDiv + divLimbsDirect cases.
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
eth-zig Ready Ready Preview, Comment Jul 15, 2026 5:23pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

safeDiv now avoids builtin u256 division by using the existing limb-based division path while retaining nullable divide-by-zero behavior.

Changes

Safe division

Layer / File(s) Summary
Limb-based safeDiv implementation
src/uint256.zig
safeDiv converts operands to limb arrays, calls divLimbsDirect, and converts the quotient back to u256; zero divisors still return null.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main performance change to safeDiv.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch koko/uint256-safediv-fast-path

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

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
src/uint256.zig (1)

90-92: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add multi-limb regression coverage for safeDiv.

The current tests only exercise the single-limb divisor path (6 / 3). Add parity cases against builtin a / b covering 2–4-limb operands, a < b, a == b, MAX, and divisors near limb boundaries so regressions in div2by2 or knuthDivCore are detected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/uint256.zig` around lines 90 - 92, Add regression tests for safeDiv
covering 2–4-limb operands and comparing results with builtin a / b, including a
< b, a == b, MAX, and divisors near limb boundaries. Reuse the existing test
structure and ensure cases exercise both div2by2 and knuthDivCore paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/uint256.zig`:
- Around line 90-92: Add regression tests for safeDiv covering 2–4-limb operands
and comparing results with builtin a / b, including a < b, a == b, MAX, and
divisors near limb boundaries. Reuse the existing test structure and ensure
cases exercise both div2by2 and knuthDivCore paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 78ae2ee2-4a15-45b6-af17-e7e2f28f6179

📥 Commits

Reviewing files that changed from the base of the PR and between 2860a47 and f23dee1.

📒 Files selected for processing (1)
  • src/uint256.zig

@koko1123
koko1123 merged commit 9da2547 into main Jul 15, 2026
13 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.

1 participant