Commit fc44cbd7 authored by Kirill Smelkov's avatar Kirill Smelkov

go/internal/xzlib: Try to reuse zlib decoders

name                 old time/op    new time/op    delta
unzlib/py/wczdata      20.7µs ± 2%    20.8µs ± 2%     ~     (p=0.548 n=5+5)
unzlib/go/wczdata      70.6µs ± 0%    64.4µs ± 1%   -8.85%  (p=0.008 n=5+5)
unzlib/py/prod1-avg    4.02µs ± 1%    4.00µs ± 1%     ~     (p=0.167 n=5+5)
unzlib/go/prod1-avg    15.2µs ± 0%    10.4µs ± 1%  -31.59%  (p=0.008 n=5+5)

still on wczdata and prod1 much slower compared to py/c zlib.
parent 91a8afa8
......@@ -24,6 +24,7 @@ import (
"bytes"
"compress/zlib"
"io"
"sync"
)
// Compress compresses data according to zlib encoding.
......@@ -43,6 +44,41 @@ func Compress(data []byte) (zdata []byte) {
return b.Bytes()
}
// ---- zlib.Reader pool ----
// (creating zlib.NewReader for every decompress has high overhead for not large blocks)
// znull is a small valid zlib stream.
// we need it to create new zlib readers under sync.Pool .
var znull = Compress(nil)
var zrPool = sync.Pool{New: func() interface{} {
r, err := zlib.NewReader(bytes.NewReader(znull))
if err != nil {
panic(err) // must not happen - znull is valid stream
}
return r
}}
// interface actually implemented by what zlib.NewReader returns
type zlibReader interface {
io.ReadCloser
zlib.Resetter
}
func zlibNewReader(r io.Reader) (zlibReader, error) {
zr := zrPool.Get().(zlibReader)
err := zr.Reset(r, nil)
if err != nil {
zlibFreeReader(zr)
return nil, err
}
return zr, nil
}
func zlibFreeReader(r zlibReader) {
zrPool.Put(r)
}
// Decompress decompresses data according to zlib encoding.
//
// out buffer, if there is enough capacity, is used for decompression destination.
......@@ -51,7 +87,7 @@ func Compress(data []byte) (zdata []byte) {
// return: destination buffer with full decompressed data or error.
func Decompress(zdata []byte, out []byte) (data []byte, err error) {
bin := bytes.NewReader(zdata)
zr, err := zlib.NewReader(bin)
zr, err := zlibNewReader(bin)
if err != nil {
return nil, err
}
......@@ -61,6 +97,7 @@ func Decompress(zdata []byte, out []byte) (data []byte, err error) {
err = err2
data = nil
}
zlibFreeReader(zr)
}()
bout := bytes.NewBuffer(out[:0])
......
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