From f23dee19edc8c13bec8652b4d927c315f5dd9ad2 Mon Sep 17 00:00:00 2001 From: Koko Bhadra Date: Wed, 15 Jul 2026 13:22:21 -0400 Subject: [PATCH] perf: route safeDiv through divLimbsDirect (not the builtin u256 /) 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. --- src/uint256.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/uint256.zig b/src/uint256.zig index c96fc62..9af80bb 100644 --- a/src/uint256.zig +++ b/src/uint256.zig @@ -82,9 +82,14 @@ pub fn safeMul(a: u256, b: u256) ?u256 { } /// Division (returns null on divide by zero). +/// +/// Routes through the limb-based `divLimbsDirect` rather than the builtin +/// `u256 /`, which lowers to a slow software long-division on aarch64 +/// (measured ~330ns for a 256/128-bit divide vs a few tens of ns here). Same +/// fast path `mulDiv` and the dex math already use. pub fn safeDiv(a: u256, b: u256) ?u256 { if (b == 0) return null; - return a / b; + return limbsToU256(divLimbsDirect(u256ToLimbs(a), u256ToLimbs(b))); } /// Fast u256 division using u64-limb schoolbook algorithm.