Commit f1583bb9 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

encoding/json: allocate less in NewEncoder

The *Encoder is almost always garbage. It doesn't need an
encodeState inside of it (and its bytes.Buffer), since it's
only needed locally inside of Encode.

benchmark                 old ns/op    new ns/op    delta
BenchmarkEncoderEncode         2562         2553   -0.35%

benchmark                 old bytes    new bytes    delta
BenchmarkEncoderEncode          283          102  -63.96%

R=r
CC=gobot, golang-dev
https://golang.org/cl/9365044
parent d73452b3
......@@ -227,6 +227,26 @@ type encodeState struct {
scratch [64]byte
}
// TODO(bradfitz): use a sync.Cache here
var encodeStatePool = make(chan *encodeState, 8)
func newEncodeState() *encodeState {
select {
case e := <-encodeStatePool:
e.Reset()
return e
default:
return new(encodeState)
}
}
func putEncodeState(e *encodeState) {
select {
case encodeStatePool <- e:
default:
}
}
func (e *encodeState) marshal(v interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
......
......@@ -156,8 +156,8 @@ func (enc *Encoder) Encode(v interface{}) error {
if enc.err != nil {
return enc.err
}
enc.e.Reset()
err := enc.e.marshal(v)
e := newEncodeState()
err := e.marshal(v)
if err != nil {
return err
}
......@@ -168,11 +168,12 @@ func (enc *Encoder) Encode(v interface{}) error {
// is required if the encoded value was a number,
// so that the reader knows there aren't more
// digits coming.
enc.e.WriteByte('\n')
e.WriteByte('\n')
if _, err = enc.w.Write(enc.e.Bytes()); err != nil {
if _, err = enc.w.Write(e.Bytes()); err != nil {
enc.err = err
}
putEncodeState(e)
return err
}
......
......@@ -191,3 +191,16 @@ func TestBlocking(t *testing.T) {
w.Close()
}
}
func BenchmarkEncoderEncode(b *testing.B) {
b.ReportAllocs()
type T struct {
X, Y string
}
v := &T{"foo", "bar"}
for i := 0; i < b.N; i++ {
if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
b.Fatal(err)
}
}
}
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