Skip to content

Commit

Permalink
log: optimize itoa
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
martisch authored and robpike committed Jan 9, 2015
1 parent 1de9c40 commit a3876ac
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
21 changes: 9 additions & 12 deletions src/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:]...)
}

Expand Down
24 changes: 24 additions & 0 deletions src/log/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit a3876ac

Please sign in to comment.