From b219e8cbcf67e10b47ab6ebe97eb6497f6010000 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 6 Dec 2011 13:54:22 -0800 Subject: [PATCH] strconv: squeezed a bit more out of int/uint formatting - less code - slightly better performance (0-4%) R=r, rsc CC=golang-dev https://golang.org/cl/5448120 --- src/pkg/strconv/itoa.go | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/pkg/strconv/itoa.go b/src/pkg/strconv/itoa.go index 794ef370b26..65229f704b8 100644 --- a/src/pkg/strconv/itoa.go +++ b/src/pkg/strconv/itoa.go @@ -12,7 +12,7 @@ func FormatUint(i uint64, base int) string { // FormatInt returns the string representation of i in the given base. func FormatInt(i int64, base int) string { - _, s := formatBits(nil, uint64(i), base, true, false) + _, s := formatBits(nil, uint64(i), base, i < 0, false) return s } @@ -24,7 +24,7 @@ func Itoa(i int) string { // AppendInt appends the string form of the integer i, // as generated by FormatInt, to dst and returns the extended buffer. func AppendInt(dst []byte, i int64, base int) []byte { - dst, _ = formatBits(dst, uint64(i), base, true, true) + dst, _ = formatBits(dst, uint64(i), base, i < 0, true) return dst } @@ -46,31 +46,21 @@ var shifts = [len(digits) + 1]uint{ } // formatBits computes the string representation of u in the given base. -// If signed is set, u is treated as int64 value. If append_ is set, the -// string is appended to dst and the resulting byte slice is returned as -// the first result value; otherwise the string is simply returned as the -// second result value. +// If negative is set, u is treated as negative int64 value. If append_ +// is set, the string is appended to dst and the resulting byte slice is +// returned as the first result value; otherwise the string is returned +// as the second result value. // -func formatBits(dst []byte, u uint64, base int, signed, append_ bool) (d []byte, s string) { +func formatBits(dst []byte, u uint64, base int, negative, append_ bool) (d []byte, s string) { if base < 2 || base > len(digits) { panic("invalid base") } // 2 <= base && base <= len(digits) - if u == 0 { - if append_ { - d = append(dst, '0') - return - } - s = "0" - return - } - var a [64 + 1]byte // +1 for sign of 64bit value in base 2 i := len(a) - x := int64(u) - if x < 0 && signed { + if negative { u = -u } @@ -78,7 +68,7 @@ func formatBits(dst []byte, u uint64, base int, signed, append_ bool) (d []byte, if base == 10 { // common case: use constant 10 for / and % because // the compiler can optimize it into a multiply+shift - for u != 0 { + for u >= 10 { i-- a[i] = digits[u%10] u /= 10 @@ -86,8 +76,9 @@ func formatBits(dst []byte, u uint64, base int, signed, append_ bool) (d []byte, } else if s := shifts[base]; s > 0 { // base is power of 2: use shifts and masks instead of / and % - m := uintptr(1)<= b { i-- a[i] = digits[uintptr(u)&m] u >>= s @@ -96,15 +87,19 @@ func formatBits(dst []byte, u uint64, base int, signed, append_ bool) (d []byte, } else { // general case b := uint64(base) - for u != 0 { + for u >= b { i-- a[i] = digits[u%b] u /= b } } + // u < base + i-- + a[i] = digits[uintptr(u)] + // add sign, if any - if x < 0 && signed { + if negative { i-- a[i] = '-' }