diff options
| author | Rob Pike <r@golang.org> | 2014-10-17 20:51:15 -0700 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2014-10-17 20:51:15 -0700 |
| commit | 65dde1ed4b1c71fad6d2b106b779c5191e5f7cd7 (patch) | |
| tree | f64040a4c614c3203b10e39b5678ae66cb91a9d7 /src/encoding/gob/encoder.go | |
| parent | 9965e4022030f56fc241be8934d5e6b95ac84900 (diff) | |
| download | go-65dde1ed4b1c71fad6d2b106b779c5191e5f7cd7.tar.xz | |
encoding/gob: use simple append-only buffer for encoding
Bytes buffers have more API and are a little slower. Since appending
is a key part of the path in encode, using a faster implementation
speeds things up measurably.
The couple of positive swings are likely garbage-collection related
since memory allocation looks different in the benchmark now.
I am not concerned by them.
benchmark old ns/op new ns/op delta
BenchmarkEndToEndPipe 6620 6388 -3.50%
BenchmarkEndToEndByteBuffer 3548 3600 +1.47%
BenchmarkEndToEndSliceByteBuffer 336678 367980 +9.30%
BenchmarkEncodeComplex128Slice 78199 71297 -8.83%
BenchmarkEncodeFloat64Slice 37731 32258 -14.51%
BenchmarkEncodeInt32Slice 26780 22977 -14.20%
BenchmarkEncodeStringSlice 35882 26492 -26.17%
BenchmarkDecodeComplex128Slice 194819 185126 -4.98%
BenchmarkDecodeFloat64Slice 120538 120102 -0.36%
BenchmarkDecodeInt32Slice 106442 107275 +0.78%
BenchmarkDecodeStringSlice 272902 269866 -1.11%
LGTM=ruiu
R=golang-codereviews, ruiu
CC=golang-codereviews
https://golang.org/cl/160990043
Diffstat (limited to 'src/encoding/gob/encoder.go')
| -rw-r--r-- | src/encoding/gob/encoder.go | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/src/encoding/gob/encoder.go b/src/encoding/gob/encoder.go index 4b5dc16c79..a340e47b5e 100644 --- a/src/encoding/gob/encoder.go +++ b/src/encoding/gob/encoder.go @@ -5,7 +5,6 @@ package gob import ( - "bytes" "io" "reflect" "sync" @@ -19,7 +18,7 @@ type Encoder struct { sent map[reflect.Type]typeId // which types we've already sent countState *encoderState // stage for writing counts freeList *encoderState // list of free encoderStates; avoids reallocation - byteBuf bytes.Buffer // buffer for top-level encoderState + byteBuf encBuffer // buffer for top-level encoderState err error } @@ -34,7 +33,7 @@ func NewEncoder(w io.Writer) *Encoder { enc := new(Encoder) enc.w = []io.Writer{w} enc.sent = make(map[reflect.Type]typeId) - enc.countState = enc.newEncoderState(new(bytes.Buffer)) + enc.countState = enc.newEncoderState(new(encBuffer)) return enc } @@ -60,7 +59,7 @@ func (enc *Encoder) setError(err error) { } // writeMessage sends the data item preceded by a unsigned count of its length. -func (enc *Encoder) writeMessage(w io.Writer, b *bytes.Buffer) { +func (enc *Encoder) writeMessage(w io.Writer, b *encBuffer) { // Space has been reserved for the length at the head of the message. // This is a little dirty: we grab the slice from the bytes.Buffer and massage // it by hand. |
