Commit 3058b1f5 authored by Bryan C. Mills's avatar Bryan C. Mills Committed by Bryan Mills

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 9d37d4c8
......@@ -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) {
......
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