From bb6375f4c856c603e34db6f2798b94485d240ac9 Mon Sep 17 00:00:00 2001 From: Erik Dubbelboer Date: Tue, 29 Nov 2016 08:44:39 +0000 Subject: [PATCH] Allow reusing of buffer in BuildBytes() This adds an optional parameter to BuildBytes() which allows for reusing of a byte buffer. Because it's an optional parameter it will not break backwards compatibility. This allows people to use a sync.Pool for the buffers used by BuildBytes() to reduce garbage generation. --- buffer/pool.go | 17 ++++++++++++----- jwriter/writer.go | 7 ++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/buffer/pool.go b/buffer/pool.go index 4de4a51..42d9886 100644 --- a/buffer/pool.go +++ b/buffer/pool.go @@ -179,18 +179,25 @@ func (b *Buffer) DumpTo(w io.Writer) (written int, err error) { } // BuildBytes creates a single byte slice with all the contents of the buffer. Data is -// copied if it does not fit in a single chunk. -func (b *Buffer) BuildBytes() []byte { +// copied if it does not fit in a single chunk. You can optionally provide one byte +// slice as argument that it will try to reuse. +func (b *Buffer) BuildBytes(reuse ...[]byte) []byte { if len(b.bufs) == 0 { - ret := b.Buf b.toPool = nil b.Buf = nil - return ret } - ret := make([]byte, 0, b.Size()) + var ret []byte + size := b.Size() + + // If we got a buffer as argument and it is big enought, reuse it. + if len(reuse) == 1 && cap(reuse[0]) >= size { + ret = reuse[0][:0] + } else { + ret = make([]byte, 0, size) + } for _, buf := range b.bufs { ret = append(ret, buf...) putBuf(buf) diff --git a/jwriter/writer.go b/jwriter/writer.go index a3ef534..ca644ec 100644 --- a/jwriter/writer.go +++ b/jwriter/writer.go @@ -37,13 +37,14 @@ func (w *Writer) DumpTo(out io.Writer) (written int, err error) { return w.Buffer.DumpTo(out) } -// BuildBytes returns writer data as a single byte slice. -func (w *Writer) BuildBytes() ([]byte, error) { +// BuildBytes returns writer data as a single byte slice. You can optionally provide one byte slice +// as argument that it will try to reuse. +func (w *Writer) BuildBytes(reuse ...[]byte) ([]byte, error) { if w.Error != nil { return nil, w.Error } - return w.Buffer.BuildBytes(), nil + return w.Buffer.BuildBytes(reuse...), nil } // RawByte appends raw binary data to the buffer.