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
})
}
+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.
// 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]