]> Cypherpunks repositories - gostls13.git/commitdiff
gob: use bufio on the decode to avoid a system call on each read.
authorRob Pike <r@golang.org>
Sat, 12 Mar 2011 00:24:09 +0000 (16:24 -0800)
committerRob Pike <r@golang.org>
Sat, 12 Mar 2011 00:24:09 +0000 (16:24 -0800)
Add a benchmark.
BenchmarkEndToEndPipe gives 14.3microseconds/op before,
13.1microseconds/op after, or about 76e3 round trips per second
through the kernel.
With a bytes buffer, and therefore no system calls for I/O, the
numbers go to 7.3microseconds/op, or about 137e3 round trips
per second.

R=rsc
CC=golang-dev
https://golang.org/cl/4279045

src/pkg/gob/decoder.go
src/pkg/gob/encoder_test.go

index 7192745836942a9f050ba3368a88871428f801c7..0c5fbbd7eab0d5a2e95e1af612636ffbea190e04 100644 (file)
@@ -5,6 +5,7 @@
 package gob
 
 import (
+       "bufio"
        "bytes"
        "io"
        "os"
@@ -30,7 +31,7 @@ type Decoder struct {
 // NewDecoder returns a new decoder that reads from the io.Reader.
 func NewDecoder(r io.Reader) *Decoder {
        dec := new(Decoder)
-       dec.r = r
+       dec.r = bufio.NewReader(r)
        dec.wireType = make(map[typeId]*wireType)
        dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
        dec.ignorerCache = make(map[typeId]**decEngine)
index a0c713b81dfa0357119b5a2e8ce763002897be7d..8155a9511b2fe99c0b05cf685c4a577fa6dfcf2b 100644 (file)
@@ -514,3 +514,39 @@ func TestNestedInterfaces(t *testing.T) {
                t.Fatalf("final value %d; expected %d", inner.A, 7)
        }
 }
+
+type Bench struct {
+       A int
+       B float64
+       C string
+       D []byte
+}
+
+func benchmarkEndToEnd(r io.Reader, w io.Writer, b *testing.B) {
+       b.StopTimer()
+       enc := NewEncoder(w)
+       dec := NewDecoder(r)
+       bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
+       b.StartTimer()
+       for i := 0; i < b.N; i++ {
+               if enc.Encode(bench) != nil {
+                       panic("encode error")
+               }
+               if dec.Decode(bench) != nil {
+                       panic("decode error")
+               }
+       }
+}
+
+func BenchmarkEndToEndPipe(b *testing.B) {
+       r, w, err := os.Pipe()
+       if err != nil {
+               panic("can't get pipe:" + err.String())
+       }
+       benchmarkEndToEnd(r, w, b)
+}
+
+func BenchmarkEndToEndByteBuffer(b *testing.B) {
+       var buf bytes.Buffer
+       benchmarkEndToEnd(&buf, &buf, b)
+}