aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/gob/timing_test.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2014-10-17 12:37:41 -0700
committerRob Pike <r@golang.org>2014-10-17 12:37:41 -0700
commit9965e4022030f56fc241be8934d5e6b95ac84900 (patch)
tree08efd013bcfb057a883b25c61df1e379afee721f /src/encoding/gob/timing_test.go
parentf4de59e234bfa7fb2a3a86764f390b09d4249a9b (diff)
downloadgo-9965e4022030f56fc241be8934d5e6b95ac84900.tar.gz
go-9965e4022030f56fc241be8934d5e6b95ac84900.zip
encoding/gob: custom array/slice decoders
Use go generate to write better loops for decoding arrays, just as we did for encoding. It doesn't help as much, relatively speaking, but it's still noticeable. benchmark old ns/op new ns/op delta BenchmarkDecodeComplex128Slice 202348 184529 -8.81% BenchmarkDecodeFloat64Slice 135800 120979 -10.91% BenchmarkDecodeInt32Slice 121200 105149 -13.24% BenchmarkDecodeStringSlice 288129 278214 -3.44% LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/154420044
Diffstat (limited to 'src/encoding/gob/timing_test.go')
-rw-r--r--src/encoding/gob/timing_test.go144
1 files changed, 136 insertions, 8 deletions
diff --git a/src/encoding/gob/timing_test.go b/src/encoding/gob/timing_test.go
index abfe936e83..940e5ad412 100644
--- a/src/encoding/gob/timing_test.go
+++ b/src/encoding/gob/timing_test.go
@@ -132,13 +132,14 @@ func TestCountDecodeMallocs(t *testing.T) {
}
}
-func BenchmarkComplex128Slice(b *testing.B) {
+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)
@@ -148,13 +149,14 @@ func BenchmarkComplex128Slice(b *testing.B) {
}
}
-func BenchmarkInt32Slice(b *testing.B) {
+func BenchmarkEncodeFloat64Slice(b *testing.B) {
var buf bytes.Buffer
enc := NewEncoder(&buf)
- a := make([]int32, 1000)
+ a := make([]float64, 1000)
for i := range a {
- a[i] = 1234
+ a[i] = 1.23e4
}
+ b.ResetTimer()
for i := 0; i < b.N; i++ {
buf.Reset()
err := enc.Encode(a)
@@ -164,13 +166,14 @@ func BenchmarkInt32Slice(b *testing.B) {
}
}
-func BenchmarkFloat64Slice(b *testing.B) {
+func BenchmarkEncodeInt32Slice(b *testing.B) {
var buf bytes.Buffer
enc := NewEncoder(&buf)
- a := make([]float64, 1000)
+ a := make([]int32, 1000)
for i := range a {
- a[i] = 1.23e4
+ a[i] = 1234
}
+ b.ResetTimer()
for i := 0; i < b.N; i++ {
buf.Reset()
err := enc.Encode(a)
@@ -180,13 +183,14 @@ func BenchmarkFloat64Slice(b *testing.B) {
}
}
-func BenchmarkStringSlice(b *testing.B) {
+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)
@@ -195,3 +199,127 @@ func BenchmarkStringSlice(b *testing.B) {
}
}
}
+
+// benchmarkBuf is a read buffer we can reset
+type benchmarkBuf struct {
+ offset int
+ data []byte
+}
+
+func (b *benchmarkBuf) Read(p []byte) (n int, err error) {
+ n = copy(p, b.data[b.offset:])
+ if n == 0 {
+ return 0, io.EOF
+ }
+ b.offset += n
+ return
+}
+
+func (b *benchmarkBuf) ReadByte() (c byte, err error) {
+ if b.offset >= len(b.data) {
+ return 0, io.EOF
+ }
+ c = b.data[b.offset]
+ b.offset++
+ return
+}
+
+func (b *benchmarkBuf) reset() {
+ b.offset = 0
+}
+
+func BenchmarkDecodeComplex128Slice(b *testing.B) {
+ 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()}
+ 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)
+ }
+ }
+}
+
+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)
+ }
+ }
+}
+
+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)
+ }
+ }
+}
+
+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)
+ }
+ }
+}