diff options
author | Martin Möhrmann <martisch@uos.de> | 2015-01-01 13:19:12 +0100 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2015-01-09 00:22:10 +0000 |
commit | a3876ac21ce4e8e5afbcee69df3cdd51e2919548 (patch) | |
tree | c8b4dfd0437205978fe49a33a5dcfcfa7cad63a0 /src/log | |
parent | 1de9c4073b7c0586c67279474bb373101d1964b8 (diff) | |
download | go-a3876ac21ce4e8e5afbcee69df3cdd51e2919548.tar.gz go-a3876ac21ce4e8e5afbcee69df3cdd51e2919548.zip |
log: optimize itoa
Reduce buffer to maximally needed size for conversion of 64bit integers.
Reduce number of used integer divisions.
benchmark old ns/op new ns/op delta
BenchmarkItoa 144 119 -17.36%
BenchmarkPrintln 783 752 -3.96%
Change-Id: I6d57a7feebf90f303be5952767107302eccf4631
Reviewed-on: https://go-review.googlesource.com/2215
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/log')
-rw-r--r-- | src/log/log.go | 21 | ||||
-rw-r--r-- | src/log/log_test.go | 24 |
2 files changed, 33 insertions, 12 deletions
diff --git a/src/log/log.go b/src/log/log.go index cb5c76ba20..5ff2bc21e3 100644 --- a/src/log/log.go +++ b/src/log/log.go @@ -63,22 +63,19 @@ func New(out io.Writer, prefix string, flag int) *Logger { var std = New(os.Stderr, "", LstdFlags) // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. -// Knows the buffer has capacity. func itoa(buf *[]byte, i int, wid int) { - var u uint = uint(i) - if u == 0 && wid <= 1 { - *buf = append(*buf, '0') - return - } - // Assemble decimal in reverse order. - var b [32]byte - bp := len(b) - for ; u > 0 || wid > 0; u /= 10 { - bp-- + var b [20]byte + bp := len(b) - 1 + for i >= 10 || wid > 1 { wid-- - b[bp] = byte(u%10) + '0' + q := i / 10 + b[bp] = byte('0' + i - q*10) + bp-- + i = q } + // i < 10 + b[bp] = byte('0' + i) *buf = append(*buf, b[bp:]...) } diff --git a/src/log/log_test.go b/src/log/log_test.go index 158c3d93c7..14e0b29263 100644 --- a/src/log/log_test.go +++ b/src/log/log_test.go @@ -117,3 +117,27 @@ func TestFlagAndPrefixSetting(t *testing.T) { t.Error("message did not match pattern") } } + +func BenchmarkItoa(b *testing.B) { + dst := make([]byte, 0, 64) + for i := 0; i < b.N; i++ { + dst = dst[0:0] + itoa(&dst, 2015, 4) // year + itoa(&dst, 1, 2) // month + itoa(&dst, 30, 2) // day + itoa(&dst, 12, 2) // hour + itoa(&dst, 56, 2) // minute + itoa(&dst, 0, 2) // second + itoa(&dst, 987654, 6) // microsecond + } +} + +func BenchmarkPrintln(b *testing.B) { + const testString = "test" + var buf bytes.Buffer + l := New(&buf, "", LstdFlags) + for i := 0; i < b.N; i++ { + buf.Reset() + l.Println(testString) + } +} |