Skip to content

Commit eb12245

Browse files
FiloSottilegopherbot
authored andcommitted
math/big: fix BitLen performance regression
CL 450055 replaced BitLen with a slower constant-time implementation, which caused a performance regression in some ecosystem benchmarks. https://perf.golang.org/search?q=upload%3A20221130.13+pkg%3Agithub.com%2Fericlagergren%2Fdecimal%2Fbenchmarks Current tip vs this CL name old time/op new time/op delta Pi/foo=ericlagergren_(Go)/prec=100-4 151µs ± 0% 129µs ± 0% -14.89% (p=0.000 n=10+9) Pi/foo=ericlagergren_(GDA)/prec=100-4 305µs ± 0% 269µs ± 1% -11.88% (p=0.000 n=9+10) Pi/foo=cockroachdb/apd/prec=100-4 5.74ms ± 0% 5.33ms ± 0% -7.02% (p=0.000 n=9+10) Pi/foo=shopspring/prec=100-4 265µs ±16% 268µs ±11% ~ (p=0.796 n=10+10) Pi/foo=apmckinlay/prec=100-4 3.10µs ± 0% 3.08µs ± 0% -0.60% (p=0.000 n=8+10) Pi/foo=go-inf/prec=100-4 132µs ± 9% 137µs ± 9% ~ (p=0.182 n=10+9) Pi/foo=float64/prec=100-4 4.97µs ± 0% 4.98µs ± 0% ~ (p=0.196 n=10+10) CL 450055's parent vs this CL name old time/op new time/op delta Pi/foo=ericlagergren_(Go)/prec=100-4 129µs ± 1% 129µs ± 0% ~ (p=0.182 n=10+9) Pi/foo=ericlagergren_(GDA)/prec=100-4 267µs ± 1% 269µs ± 1% +0.93% (p=0.001 n=9+10) Pi/foo=shopspring/prec=100-4 252µs ± 9% 268µs ±11% ~ (p=0.052 n=10+10) Pi/foo=apmckinlay/prec=100-4 3.10µs ± 1% 3.08µs ± 0% -0.66% (p=0.000 n=9+10) Pi/foo=go-inf/prec=100-4 135µs ± 6% 137µs ± 9% ~ (p=0.605 n=9+9) Pi/foo=float64/prec=100-4 4.97µs ± 0% 4.98µs ± 0% +0.23% (p=0.005 n=8+10) goos: linux goarch: amd64 pkg: github.com/ericlagergren/decimal_benchmarks cpu: Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz Fixes #57014 Change-Id: I08478bea122212320a592ad2652e33077807de09 Reviewed-on: https://go-review.googlesource.com/c/go/+/454617 Reviewed-by: Roland Shoemaker <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]> Reviewed-by: Russ Cox <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 6ec6492 commit eb12245

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

src/math/big/nat.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -664,15 +664,18 @@ func (x nat) bitLen() int {
664664
// This function is used in cryptographic operations. It must not leak
665665
// anything but the Int's sign and bit size through side-channels. Any
666666
// changes must be reviewed by a security expert.
667-
//
668-
// In particular, bits.Len and bits.LeadingZeros use a lookup table for the
669-
// low-order bits on some architectures.
670667
if i := len(x) - 1; i >= 0 {
671-
l := i * _W
672-
for top := x[i]; top != 0; top >>= 1 {
673-
l++
674-
}
675-
return l
668+
// bits.Len uses a lookup table for the low-order bits on some
669+
// architectures. Neutralize any input-dependent behavior by setting all
670+
// bits after the first one bit.
671+
top := uint(x[i])
672+
top |= top >> 1
673+
top |= top >> 2
674+
top |= top >> 4
675+
top |= top >> 8
676+
top |= top >> 16
677+
top |= top >> 16 >> 16 // ">> 32" doesn't compile on 32-bit architectures
678+
return i*_W + bits.Len(top)
676679
}
677680
return 0
678681
}

0 commit comments

Comments
 (0)