strconv: remove &0xFF trick in formatBase10

The compiler is now smart enough to remove the bounds check itself.

                              │ 731f809c971  │            48fabc7d33b             │
                              │    sec/op    │   sec/op     vs base               │
AppendUint-12                    98.69n ± 1%   95.81n ± 1%  -2.91% (p=0.000 n=20)
AppendUintVarlen/digits=1-12     3.119n ± 1%   3.099n ± 1%       ~ (p=0.743 n=20)
AppendUintVarlen/digits=2-12     2.654n ± 0%   2.653n ± 0%       ~ (p=0.825 n=20)
AppendUintVarlen/digits=3-12     5.042n ± 0%   5.055n ± 1%       ~ (p=0.005 n=20)
AppendUintVarlen/digits=4-12     5.062n ± 1%   5.044n ± 0%       ~ (p=0.011 n=20)
AppendUintVarlen/digits=5-12     5.863n ± 0%   5.908n ± 1%       ~ (p=0.075 n=20)
AppendUintVarlen/digits=6-12     6.137n ± 0%   6.117n ± 1%       ~ (p=0.857 n=20)
AppendUintVarlen/digits=7-12     7.367n ± 0%   7.366n ± 0%       ~ (p=0.784 n=20)
AppendUintVarlen/digits=8-12     7.369n ± 0%   7.381n ± 0%       ~ (p=0.159 n=20)
AppendUintVarlen/digits=9-12     7.795n ± 2%   7.749n ± 0%       ~ (p=0.180 n=20)
AppendUintVarlen/digits=10-12    9.208n ± 1%   8.661n ± 0%  -5.94% (p=0.000 n=20)
AppendUintVarlen/digits=11-12    9.479n ± 1%   8.984n ± 0%  -5.22% (p=0.000 n=20)
AppendUintVarlen/digits=12-12    9.784n ± 0%   9.229n ± 1%  -5.67% (p=0.000 n=20)
AppendUintVarlen/digits=13-12   10.035n ± 1%   9.504n ± 0%  -5.29% (p=0.000 n=20)
AppendUintVarlen/digits=14-12    10.89n ± 1%   10.35n ± 0%  -4.96% (p=0.000 n=20)
AppendUintVarlen/digits=15-12    11.12n ± 0%   10.61n ± 1%  -4.67% (p=0.000 n=20)
AppendUintVarlen/digits=16-12    12.29n ± 0%   11.85n ± 1%  -3.62% (p=0.000 n=20)
AppendUintVarlen/digits=17-12    12.32n ± 0%   11.85n ± 1%  -3.85% (p=0.000 n=20)
AppendUintVarlen/digits=18-12    12.80n ± 0%   12.32n ± 1%  -3.79% (p=0.000 n=20)
AppendUintVarlen/digits=19-12    14.62n ± 1%   13.71n ± 1%  -6.29% (p=0.000 n=20)
AppendUintVarlen/digits=20-12    14.83n ± 0%   13.93n ± 0%  -6.10% (p=0.000 n=20)
geomean                          9.102n        8.843n       -2.84%

Change-Id: Ic8c79b472d5c30dccc1d974b47647f6425618e00
Reviewed-on: https://go-review.googlesource.com/c/go/+/714161
Auto-Submit: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Russ Cox 2025-10-23 09:42:37 -04:00 committed by Gopher Robot
parent 9bbda7c99d
commit d2c5fa0814

View file

@ -156,10 +156,6 @@ const nSmalls = 100
// smalls is the formatting of 00..99 concatenated.
// It is then padded out with 56 x's to 256 bytes,
// so that smalls[x&0xFF] has no bounds check.
//
// TODO(rsc): Once the compiler does a better job
// at tracking mod bounds, the &0xFF should not be needed:
// go.dev/issue/75954 and go.dev/issue/63110.
const smalls = "00010203040506070809" +
"10111213141516171819" +
"20212223242526272829" +
@ -169,13 +165,7 @@ const smalls = "00010203040506070809" +
"60616263646566676869" +
"70717273747576777879" +
"80818283848586878889" +
"90919293949596979899" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxx"
"90919293949596979899"
const host64bit = ^uint(0)>>32 != 0
@ -215,15 +205,15 @@ func formatBase10(a []byte, u uint64) int {
var dd uint
u, dd = u/100, (u%100)*2
i -= 2
a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
a[i+0], a[i+1] = smalls[dd+0], smalls[dd+1]
}
dd := u * 2
i--
a[i] = smalls[(dd+1)&0xFF]
a[i] = smalls[dd+1]
if u >= 10 {
i--
a[i] = smalls[(dd+0)&0xFF]
a[i] = smalls[dd]
}
return i
}
@ -275,10 +265,10 @@ func formatBase10(a []byte, u uint64) int {
var dd uint32
lo, dd = lo/100, (lo%100)*2
i -= 2
a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
a[i+0], a[i+1] = smalls[dd+0], smalls[dd+1]
}
i--
a[i] = smalls[(lo*2+1)&0xFF]
a[i] = smalls[lo*2+1]
// If we'd been using u >= 1e9 then we would be guaranteed that u/1e9 > 0,
// but since we used u>>29 != 0, u/1e9 might be 0, so we might be done.
@ -295,14 +285,14 @@ func formatBase10(a []byte, u uint64) int {
var dd uint32
lo, dd = lo/100, (lo%100)*2
i -= 2
a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
a[i+0], a[i+1] = smalls[dd+0], smalls[dd+1]
}
i--
dd := lo * 2
a[i] = smalls[(dd+1)&0xFF]
a[i] = smalls[dd+1]
if lo >= 10 {
i--
a[i] = smalls[(dd+0)&0xFF]
a[i] = smalls[dd+0]
}
return i
}