]> Cypherpunks repositories - gostls13.git/commitdiff
strconv: remove &0xFF trick in formatBase10
authorRuss Cox <rsc@golang.org>
Thu, 23 Oct 2025 13:42:37 +0000 (09:42 -0400)
committerGopher Robot <gobot@golang.org>
Thu, 30 Oct 2025 02:16:37 +0000 (19:16 -0700)
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>
src/internal/strconv/itoa.go

index d4ca478eb0abe9e06e3c5cebfa851e6109f9c9ca..d166731ea5d3f4c61cba4cc024cd61b5938798f8 100644 (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
 }