Commit b1accced authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

strings: add Builder benchmarks comparing bytes.Buffer and strings.Builder

Despite the existing test that locks in the allocation behavior, people
really want a benchmark. So:

BenchmarkBuildString_Builder/1Write_NoGrow-4    20000000  60.4 ns/op   48 B/op  1 allocs/op
BenchmarkBuildString_Builder/3Write_NoGrow-4    10000000   230 ns/op  336 B/op  3 allocs/op
BenchmarkBuildString_Builder/3Write_Grow-4      20000000   102 ns/op  112 B/op  1 allocs/op
BenchmarkBuildString_ByteBuffer/1Write_NoGrow-4 10000000   125 ns/op  160 B/op  2 allocs/op
BenchmarkBuildString_ByteBuffer/3Write_NoGrow-4  5000000   339 ns/op  400 B/op  3 allocs/op
BenchmarkBuildString_ByteBuffer/3Write_Grow-4    5000000   316 ns/op  336 B/op  3 allocs/op

I don't think these allocate-as-fast-as-you-can benchmarks are very
interesting because they're effectively just GC benchmarks, but sure.
If one wants to see that there's 1 fewer allocation, there it is. The
ns/op and B/op numbers will change as the built string size changes.

Updates #18990

Change-Id: Ifccf535bd396217434a0e6989e195105f90132ae
Reviewed-on: https://go-review.googlesource.com/96980
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 495eb3f9
...@@ -302,3 +302,52 @@ func TestBuilderCopyPanic(t *testing.T) { ...@@ -302,3 +302,52 @@ func TestBuilderCopyPanic(t *testing.T) {
} }
} }
} }
var someBytes = []byte("some bytes sdljlk jsklj3lkjlk djlkjw")
var sinkS string
func benchmarkBuilder(b *testing.B, f func(b *testing.B, numWrite int, grow bool)) {
b.Run("1Write_NoGrow", func(b *testing.B) {
b.ReportAllocs()
f(b, 1, false)
})
b.Run("3Write_NoGrow", func(b *testing.B) {
b.ReportAllocs()
f(b, 3, false)
})
b.Run("3Write_Grow", func(b *testing.B) {
b.ReportAllocs()
f(b, 3, true)
})
}
func BenchmarkBuildString_Builder(b *testing.B) {
benchmarkBuilder(b, func(b *testing.B, numWrite int, grow bool) {
for i := 0; i < b.N; i++ {
var buf Builder
if grow {
buf.Grow(len(someBytes) * numWrite)
}
for i := 0; i < numWrite; i++ {
buf.Write(someBytes)
}
sinkS = buf.String()
}
})
}
func BenchmarkBuildString_ByteBuffer(b *testing.B) {
benchmarkBuilder(b, func(b *testing.B, numWrite int, grow bool) {
for i := 0; i < b.N; i++ {
var buf bytes.Buffer
if grow {
buf.Grow(len(someBytes) * numWrite)
}
for i := 0; i < numWrite; i++ {
buf.Write(someBytes)
}
sinkS = buf.String()
}
})
}
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