]> Cypherpunks repositories - gostls13.git/commitdiff
strings: add Builder benchmarks comparing bytes.Buffer and strings.Builder
authorBrad Fitzpatrick <bradfitz@golang.org>
Sun, 25 Feb 2018 16:41:22 +0000 (16:41 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 26 Feb 2018 18:00:12 +0000 (18:00 +0000)
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: Alan Donovan <adonovan@google.com>
src/strings/builder_test.go

index ecbaeaa5c17c0ced0500d3939eb2f8c0002320db..29d49e98a72effd9c9507edd78df48e9296dbe4c 100644 (file)
@@ -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()
+               }
+       })
+}