gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit be3d98c46fee4dac764ce13df59c905dbf5ad4b6
parent 514aec19fd89e723006ae08b3dcc094a206e85d4
Author: francoispqt <francois@parquet.ninja>
Date:   Sun,  6 May 2018 11:53:22 +0800

add buf management optimisation for encoding

Diffstat:
Mencode.go | 2+-
Mencode_pool.go | 41++++++++++++++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/encode.go b/encode.go @@ -190,6 +190,6 @@ func (enc *Encoder) getPreviousRune() (byte, bool) { func (enc *Encoder) write() (int, error) { i, err := enc.w.Write(enc.buf) - enc.buf = make([]byte, 0, 512) + enc.buf = enc.buf[:0] return i, err } diff --git a/encode_pool.go b/encode_pool.go @@ -4,6 +4,33 @@ import "io" var encPool = make(chan *Encoder, 16) var streamEncPool = make(chan *StreamEncoder, 16) +var bufPool = make(chan []byte, 16) + +func init() { +initStreamEncPool: + for { + select { + case streamEncPool <- Stream.NewEncoder(nil): + default: + break initStreamEncPool + } + } +initEncPool: + for { + select { + case encPool <- NewEncoder(nil): + default: + break initEncPool + } + } + for { + select { + case bufPool <- make([]byte, 0, 512): + default: + return + } + } +} // NewEncoder returns a new encoder or borrows one from the pool func NewEncoder(w io.Writer) *Encoder { @@ -20,19 +47,27 @@ func BorrowEncoder(w io.Writer) *Encoder { enc.isPooled = 0 enc.w = w enc.err = nil - enc.buf = make([]byte, 0) return enc default: - return &Encoder{w: w} + return &Encoder{w: w, buf: borrowBuf()} } } // Release sends back a Encoder to the pool. func (enc *Encoder) Release() { - enc.buf = nil + enc.buf = enc.buf[:0] enc.isPooled = 1 select { case encPool <- enc: default: } } + +func borrowBuf() []byte { + select { + case b := <-bufPool: + return b + default: + return make([]byte, 0, 512) + } +}