Use a buffer pool in report.ReadBinary() to reduce garbage-collection

This commit is contained in:
Bryan Boreham
2018-07-04 13:35:44 +00:00
parent 3656513af6
commit 84169c6c55

View File

@@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
log "github.com/Sirupsen/logrus"
"github.com/ugorji/go/codec"
@@ -61,13 +62,18 @@ func (c byteCounter) Read(p []byte) (n int, err error) {
return n, err
}
// buffer pool to reduce garbage-collection
var bufferPool = &sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}
// ReadBinary reads bytes into a Report.
//
// Will decompress the binary if gzipped is true, and will use the given
// codecHandle to decode it.
func (rep *Report) ReadBinary(r io.Reader, gzipped bool, codecHandle codec.Handle) error {
var err error
var compressedSize, uncompressedSize uint64
var compressedSize uint64
// We have historically had trouble with reports being too large. We are
// keeping this instrumentation around to help us implement
@@ -82,12 +88,14 @@ func (rep *Report) ReadBinary(r io.Reader, gzipped bool, codecHandle codec.Handl
}
}
// Read everything into memory before decoding: it's faster
buf, err := ioutil.ReadAll(r)
buf := bufferPool.Get().(*bytes.Buffer)
buf.Reset()
defer bufferPool.Put(buf)
uncompressedSize, err := buf.ReadFrom(r)
if err != nil {
return err
}
uncompressedSize = uint64(len(buf))
if err := rep.ReadBytes(buf, codecHandle); err != nil {
if err := rep.ReadBytes(buf.Bytes(), codecHandle); err != nil {
return err
}
log.Debugf(