diff options
author | Bryan C. Mills <bcmills@google.com> | 2017-02-10 14:13:06 -0500 |
---|---|---|
committer | Bryan Mills <bcmills@google.com> | 2017-04-26 19:04:18 +0000 |
commit | 3058b1f5382ce645fc22fc09127213feb3032a20 (patch) | |
tree | 35ead9df54aa6ced28dab67c1bb5c576b911bd11 /src/encoding/gob/timing_test.go | |
parent | 9d37d4c88abc1920e45abc7c2c80a156420090fe (diff) | |
download | go-3058b1f5382ce645fc22fc09127213feb3032a20.tar.gz go-3058b1f5382ce645fc22fc09127213feb3032a20.zip |
encoding/gob: parallelize Encode/Decode benchmarks
Results remain comparable with the non-parallel version with -cpu=1:
benchmark old ns/op new ns/op delta
BenchmarkEndToEndPipe 6200 6171 -0.47%
BenchmarkEndToEndPipe-6 1073 1024 -4.57%
BenchmarkEndToEndByteBuffer 2925 2664 -8.92%
BenchmarkEndToEndByteBuffer-6 516 560 +8.53%
BenchmarkEndToEndSliceByteBuffer 231683 237450 +2.49%
BenchmarkEndToEndSliceByteBuffer-6 59080 59452 +0.63%
BenchmarkEncodeComplex128Slice 67541 66003 -2.28%
BenchmarkEncodeComplex128Slice-6 72740 11316 -84.44%
BenchmarkEncodeFloat64Slice 25769 27899 +8.27%
BenchmarkEncodeFloat64Slice-6 26655 4557 -82.90%
BenchmarkEncodeInt32Slice 18685 18845 +0.86%
BenchmarkEncodeInt32Slice-6 18389 3462 -81.17%
BenchmarkEncodeStringSlice 19089 19354 +1.39%
BenchmarkEncodeStringSlice-6 20155 3237 -83.94%
BenchmarkEncodeInterfaceSlice 659601 677129 +2.66%
BenchmarkEncodeInterfaceSlice-6 640974 251621 -60.74%
BenchmarkDecodeComplex128Slice 117130 129955 +10.95%
BenchmarkDecodeComplex128Slice-6 155447 24924 -83.97%
BenchmarkDecodeFloat64Slice 67695 68776 +1.60%
BenchmarkDecodeFloat64Slice-6 82966 15225 -81.65%
BenchmarkDecodeInt32Slice 63102 62733 -0.58%
BenchmarkDecodeInt32Slice-6 77857 13003 -83.30%
BenchmarkDecodeStringSlice 130240 129562 -0.52%
BenchmarkDecodeStringSlice-6 165500 31507 -80.96%
BenchmarkDecodeInterfaceSlice 937637 1060835 +13.14%
BenchmarkDecodeInterfaceSlice-6 973495 270613 -72.20%
updates #18177
Change-Id: Ib3579010faa70827d5cbd02a826dbbb66ca13eb7
Reviewed-on: https://go-review.googlesource.com/36722
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/encoding/gob/timing_test.go')
-rw-r--r-- | src/encoding/gob/timing_test.go | 185 |
1 files changed, 54 insertions, 131 deletions
diff --git a/src/encoding/gob/timing_test.go b/src/encoding/gob/timing_test.go index e3578992fc..2a503ebfc5 100644 --- a/src/encoding/gob/timing_test.go +++ b/src/encoding/gob/timing_test.go @@ -8,6 +8,7 @@ import ( "bytes" "io" "os" + "reflect" "runtime" "testing" ) @@ -132,89 +133,60 @@ func TestCountDecodeMallocs(t *testing.T) { } } +func benchmarkEncodeSlice(b *testing.B, a interface{}) { + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + + for pb.Next() { + buf.Reset() + err := enc.Encode(a) + if err != nil { + b.Fatal(err) + } + } + }) +} + func BenchmarkEncodeComplex128Slice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]complex128, 1000) for i := range a { a[i] = 1.2 + 3.4i } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - } + benchmarkEncodeSlice(b, a) } func BenchmarkEncodeFloat64Slice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]float64, 1000) for i := range a { a[i] = 1.23e4 } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - } + benchmarkEncodeSlice(b, a) } func BenchmarkEncodeInt32Slice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]int32, 1000) for i := range a { a[i] = int32(i * 100) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - } + benchmarkEncodeSlice(b, a) } func BenchmarkEncodeStringSlice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]string, 1000) for i := range a { a[i] = "now is the time" } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - } + benchmarkEncodeSlice(b, a) } func BenchmarkEncodeInterfaceSlice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]interface{}, 1000) for i := range a { a[i] = "now is the time" } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - } + benchmarkEncodeSlice(b, a) } // benchmarkBuf is a read buffer we can reset @@ -245,124 +217,75 @@ func (b *benchmarkBuf) reset() { b.offset = 0 } -func BenchmarkDecodeComplex128Slice(b *testing.B) { +func benchmarkDecodeSlice(b *testing.B, a interface{}) { var buf bytes.Buffer enc := NewEncoder(&buf) - a := make([]complex128, 1000) - for i := range a { - a[i] = 1.2 + 3.4i - } err := enc.Encode(a) if err != nil { b.Fatal(err) } - x := make([]complex128, 1000) - bbuf := benchmarkBuf{data: buf.Bytes()} + + ra := reflect.ValueOf(a) + rt := ra.Type() b.ResetTimer() - for i := 0; i < b.N; i++ { - bbuf.reset() - dec := NewDecoder(&bbuf) - err := dec.Decode(&x) - if err != nil { - b.Fatal(i, err) + + b.RunParallel(func(pb *testing.PB) { + // TODO(#19025): Move per-thread allocation before ResetTimer. + rp := reflect.New(rt) + rp.Elem().Set(reflect.MakeSlice(rt, ra.Len(), ra.Cap())) + p := rp.Interface() + + bbuf := benchmarkBuf{data: buf.Bytes()} + + for pb.Next() { + bbuf.reset() + dec := NewDecoder(&bbuf) + err := dec.Decode(p) + if err != nil { + b.Fatal(err) + } } + }) +} + +func BenchmarkDecodeComplex128Slice(b *testing.B) { + a := make([]complex128, 1000) + for i := range a { + a[i] = 1.2 + 3.4i } + benchmarkDecodeSlice(b, a) } func BenchmarkDecodeFloat64Slice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]float64, 1000) for i := range a { a[i] = 1.23e4 } - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - x := make([]float64, 1000) - bbuf := benchmarkBuf{data: buf.Bytes()} - b.ResetTimer() - for i := 0; i < b.N; i++ { - bbuf.reset() - dec := NewDecoder(&bbuf) - err := dec.Decode(&x) - if err != nil { - b.Fatal(i, err) - } - } + benchmarkDecodeSlice(b, a) } func BenchmarkDecodeInt32Slice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]int32, 1000) for i := range a { a[i] = 1234 } - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - x := make([]int32, 1000) - bbuf := benchmarkBuf{data: buf.Bytes()} - b.ResetTimer() - for i := 0; i < b.N; i++ { - bbuf.reset() - dec := NewDecoder(&bbuf) - err := dec.Decode(&x) - if err != nil { - b.Fatal(i, err) - } - } + benchmarkDecodeSlice(b, a) } func BenchmarkDecodeStringSlice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]string, 1000) for i := range a { a[i] = "now is the time" } - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - x := make([]string, 1000) - bbuf := benchmarkBuf{data: buf.Bytes()} - b.ResetTimer() - for i := 0; i < b.N; i++ { - bbuf.reset() - dec := NewDecoder(&bbuf) - err := dec.Decode(&x) - if err != nil { - b.Fatal(i, err) - } - } + benchmarkDecodeSlice(b, a) } func BenchmarkDecodeInterfaceSlice(b *testing.B) { - var buf bytes.Buffer - enc := NewEncoder(&buf) a := make([]interface{}, 1000) for i := range a { a[i] = "now is the time" } - err := enc.Encode(a) - if err != nil { - b.Fatal(err) - } - x := make([]interface{}, 1000) - bbuf := benchmarkBuf{data: buf.Bytes()} - b.ResetTimer() - for i := 0; i < b.N; i++ { - bbuf.reset() - dec := NewDecoder(&bbuf) - err := dec.Decode(&x) - if err != nil { - b.Fatal(i, err) - } - } + benchmarkDecodeSlice(b, a) } func BenchmarkDecodeMap(b *testing.B) { |