Commit 78b5321e authored by Rob Pike's avatar Rob Pike

fmt: make printing of ints 25-35% faster

Inspired by a remark by Leonard Holz, use constants for division

BenchmarkSprintfEmpty           130           132           +1.54%
BenchmarkSprintfString          438           437           -0.23%
BenchmarkSprintfInt             417           414           -0.72%
BenchmarkSprintfIntInt          663           691           +4.22%
BenchmarkSprintfPrefixedInt     791           774           -2.15%
BenchmarkSprintfFloat           701           686           -2.14%
BenchmarkManyArgs               2584          2469          -4.45%
BenchmarkFprintInt              488           357           -26.84%
BenchmarkFprintIntNoAlloc       402           265           -34.08%
BenchmarkScanInts               1244346       1267574       +1.87%
BenchmarkScanRecursiveInt       1748741       1724138       -1.41%

Update #3463

LGTM=josharian, rsc
R=golang-codereviews, josharian, rsc
CC=golang-codereviews
https://golang.org/cl/144250043
parent db56d4d5
......@@ -854,6 +854,23 @@ func BenchmarkManyArgs(b *testing.B) {
})
}
func BenchmarkFprintInt(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
Fprint(&buf, 123456)
}
}
func BenchmarkFprintIntNoAlloc(b *testing.B) {
var x interface{} = 123456
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
Fprint(&buf, x)
}
}
var mallocBuf bytes.Buffer
var mallocPointer *int // A pointer so we know the interface value won't allocate.
......
......@@ -199,10 +199,36 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
// block but it's not worth the duplication, so ua has 64 bits.
i := len(buf)
ua := uint64(a)
for ua >= base {
i--
buf[i] = digits[ua%base]
ua /= base
// use constants for the division and modulo for more efficient code.
// switch cases ordered by popularity.
switch base {
case 10:
for ua >= 10 {
i--
next := ua / 10
buf[i] = byte('0' + ua - next*10)
ua = next
}
case 16:
for ua >= 16 {
i--
buf[i] = digits[ua&0xF]
ua >>= 4
}
case 8:
for ua >= 8 {
i--
buf[i] = byte('0' + ua&7)
ua >>= 3
}
case 2:
for ua >= 2 {
i--
buf[i] = byte('0' + ua&1)
ua >>= 1
}
default:
panic("fmt: unknown base; can't happen")
}
i--
buf[i] = digits[ua]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment