]> Cypherpunks repositories - gostls13.git/commitdiff
strconv: even faster int conversion
authorRobert Griesemer <gri@golang.org>
Wed, 14 Dec 2011 18:45:59 +0000 (10:45 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 14 Dec 2011 18:45:59 +0000 (10:45 -0800)
benchmark                           old ns/op    new ns/op    delta
strconv_test.BenchmarkFormatInt         10038         8217  -18.14%
strconv_test.BenchmarkAppendInt          6822         4969  -27.16%
strconv_test.BenchmarkFormatUint         2811         1814  -35.47%
strconv_test.BenchmarkAppendUint         2349         1360  -42.10%

R=rsc
CC=golang-dev
https://golang.org/cl/5488083

src/pkg/strconv/itoa.go

index 821abe0094b2c7d115c4d6c322b9fb4888438f0a..4ef835502d4e97fb91344e032b371ae3cd310045 100644 (file)
@@ -35,7 +35,11 @@ func AppendUint(dst []byte, i uint64, base int) []byte {
        return dst
 }
 
-const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
+const (
+       digits   = "0123456789abcdefghijklmnopqrstuvwxyz"
+       digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+       digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
+)
 
 var shifts = [len(digits) + 1]uint{
        1 << 1: 1,
@@ -66,12 +70,22 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
 
        // convert bits
        if base == 10 {
-               // common case: use constant 10 for / and % because
-               // the compiler can optimize it into a multiply+shift
-               for u >= 10 {
+               // common case: use constants for / and % because
+               // the compiler can optimize it into a multiply+shift,
+               // and unroll loop
+               for u >= 100 {
+                       i -= 2
+                       q := u / 100
+                       j := u - q*100
+                       a[i+1] = digits01[j]
+                       a[i+0] = digits10[j]
+                       u = q
+               }
+               if u >= 10 {
                        i--
-                       a[i] = digits[u%10]
-                       u /= 10
+                       q := u / 10
+                       a[i] = digits[u-q*10]
+                       u = q
                }
 
        } else if s := shifts[base]; s > 0 {