Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: cbd15fc88bdeffb4618a464681e03ef1f25bc5b6
      
https://github.com/WebKit/WebKit/commit/cbd15fc88bdeffb4618a464681e03ef1f25bc5b6
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-09-04 (Fri, 04 Sep 2026)

  Changed paths:
    A JSTests/microbenchmarks/bigint-mul-large-unequal.js
    A JSTests/microbenchmarks/bigint-mul-large.js
    A JSTests/stress/bigint-multiply-karatsuba.js
    M Source/JavaScriptCore/runtime/JSBigInt.cpp
    M Source/JavaScriptCore/runtime/JSBigInt.h

  Log Message:
  -----------
  [JSC] Add Karatsuba multiplication to `JSBigInt`
https://bugs.webkit.org/show_bug.cgi?id=323244

Reviewed by Yusuke Suzuki.

JSBigInt multiplies with O(n^2) schoolbook / Comba loops only, so the time per
product grows quadratically with the operand size: 1000 x 1000 digits takes
336 us and 4000 x 4000 takes 5.3 ms. Add Karatsuba multiplication for products
whose smaller operand has at least 44 digits, which brings the growth to
O(n^1.58). This is a port of V8's implementation [1], itself based on Go's
math/big [2].

The threshold is 44 rather than V8's 34 because JSC's Comba base case is faster
than V8's schoolbook: balanced shapes win from 40 digits, but for a long x the
length rounding pads an odd smaller operand by a digit, and at 41 or 43 digits
that padding costs the 2-3% Karatsuba would gain. At 44 no measured shape
regresses. Sizes below the threshold keep the existing paths, and allocation,
sign and normalization in multiplyImpl are unchanged.

Time per product (us, 64-bit digits, Apple M4, best of 3 x 7 rounds):

digits          Before      After

40 x 40          0.647      0.652
43 x 43          0.738      0.738
44 x 44          0.762      0.714
64 x 64          1.658      1.406
100 x 100        3.987      2.872
256 x 256       23.901     13.113
1000 x 1000    335.548    122.562
4000 x 4000   5337.000   1110.688
1000 x 43       16.089     16.447
1000 x 45       16.870     16.677
10000 x 45     163.054    164.321
10000 x 100    352.316    276.342

                                   Baseline                  Patched

bigint-mul-large              249.7296+-0.6119     ^    140.1950+-0.4092        
^ definitely 1.7813x faster
bigint-mul-large-unequal      371.3519+-0.7129     ^    299.9962+-0.7217        
^ definitely 1.2379x faster

[1]: 
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/bigint/mul-karatsuba.cc
[2]: https://go.dev/src/math/big/nat.go

Tests: JSTests/microbenchmarks/bigint-mul-large-unequal.js
       JSTests/microbenchmarks/bigint-mul-large.js
       JSTests/stress/bigint-multiply-karatsuba.js

* JSTests/microbenchmarks/bigint-mul-large-unequal.js: Added.
(test):
(next):
* JSTests/microbenchmarks/bigint-mul-large.js: Added.
(test):
(next):
* JSTests/stress/bigint-multiply-karatsuba.js: Added.
(shouldBe):
(refMul):
(makeOperand):
(makeSparseOperand):
(check):
* Source/JavaScriptCore/runtime/JSBigInt.cpp:
(JSC::karatsubaRoundUpLength):
(JSC::karatsubaLength):
(JSC::clampedSubspan):
(JSC::JSBigInt::inplaceAddAndPropagate):
(JSC::JSBigInt::inplaceSubAndPropagate):
(JSC::JSBigInt::karatsubaAbsoluteDifference):
(JSC::JSBigInt::multiplyZeroPadded):
(JSC::JSBigInt::karatsubaMain):
(JSC::JSBigInt::karatsubaChunk):
(JSC::JSBigInt::karatsubaStart):
(JSC::JSBigInt::multiplyKaratsuba):
(JSC::JSBigInt::multiplyDigitsInto):
* Source/JavaScriptCore/runtime/JSBigInt.h:

Canonical link: https://commits.webkit.org/320495@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to