diff options
author | Robert Griesemer <gri@golang.org> | 2011-12-14 10:45:59 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2011-12-14 10:45:59 -0800 |
commit | 465aba66c1080b44bc669dd60aa1dc29e01c4a6f (patch) | |
tree | 17b03687832f30dd017f9c9ad161fb0b0a6617a0 | |
parent | 25e94154b719506511b16e0936dcea60846fa790 (diff) | |
download | go-465aba66c1080b44bc669dd60aa1dc29e01c4a6f.tar.gz go-465aba66c1080b44bc669dd60aa1dc29e01c4a6f.zip |
strconv: even faster int conversion
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
-rw-r--r-- | src/pkg/strconv/itoa.go | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/pkg/strconv/itoa.go b/src/pkg/strconv/itoa.go index 821abe0094..4ef835502d 100644 --- a/src/pkg/strconv/itoa.go +++ b/src/pkg/strconv/itoa.go @@ -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 { |