aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2011-12-14 10:45:59 -0800
committerRobert Griesemer <gri@golang.org>2011-12-14 10:45:59 -0800
commit465aba66c1080b44bc669dd60aa1dc29e01c4a6f (patch)
tree17b03687832f30dd017f9c9ad161fb0b0a6617a0
parent25e94154b719506511b16e0936dcea60846fa790 (diff)
downloadgo-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.go26
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 {