diff options
author | Paulo Gomes <pjbgf@linux.com> | 2022-11-04 12:44:40 +0000 |
---|---|---|
committer | Paulo Gomes <pjbgf@linux.com> | 2022-11-07 14:49:56 +0000 |
commit | 9490da0f86a12269abb2099e2ead1f20eec166d2 (patch) | |
tree | 1b6d079443203393f9e321aa91bb247ea4984cbb /utils/sync/zlib.go | |
parent | ffa7e69efb8c4ba8d4e08ec4c65e49e2228fd88b (diff) | |
download | go-git-9490da0f86a12269abb2099e2ead1f20eec166d2.tar.gz |
Optimize zlib reader and consolidate sync.pools
Expands on the optimisations from https://github.com/fluxcd/go-git/pull/5
and ensures that zlib reader does not need to recreate a deflate
dictionary at every use.
The use of sync pools was consolidated into a new sync utils package.
name old time/op new time/op delta
Parser-16 7.51ms ± 3% 7.71ms ± 6% ~ (p=0.222 n=5+5)
name old alloc/op new alloc/op delta
Parser-16 4.65MB ± 3% 1.90MB ± 3% -59.06% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
Parser-16 3.48k ± 0% 3.32k ± 0% -4.57% (p=0.016 n=5+4)
Signed-off-by: Paulo Gomes <pjbgf@linux.com>
Diffstat (limited to 'utils/sync/zlib.go')
-rw-r--r-- | utils/sync/zlib.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/utils/sync/zlib.go b/utils/sync/zlib.go new file mode 100644 index 0000000..c613885 --- /dev/null +++ b/utils/sync/zlib.go @@ -0,0 +1,74 @@ +package sync + +import ( + "bytes" + "compress/zlib" + "io" + "sync" +) + +var ( + zlibInitBytes = []byte{0x78, 0x9c, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01} + zlibReader = sync.Pool{ + New: func() interface{} { + r, _ := zlib.NewReader(bytes.NewReader(zlibInitBytes)) + return ZLibReader{ + Reader: r.(zlibReadCloser), + } + }, + } + zlibWriter = sync.Pool{ + New: func() interface{} { + return zlib.NewWriter(nil) + }, + } +) + +type zlibReadCloser interface { + io.ReadCloser + zlib.Resetter +} + +type ZLibReader struct { + dict *[]byte + Reader zlibReadCloser +} + +// GetZlibReader returns a ZLibReader that is managed by a sync.Pool. +// Returns a ZLibReader that is resetted using a dictionary that is +// also managed by a sync.Pool. +// +// After use, the ZLibReader should be put back into the sync.Pool +// by calling PutZlibReader. +func GetZlibReader(r io.Reader) (ZLibReader, error) { + z := zlibReader.Get().(ZLibReader) + z.dict = GetByteSlice() + + err := z.Reader.Reset(r, *z.dict) + + return z, err +} + +// PutZlibReader puts z back into its sync.Pool, first closing the reader. +// The Byte slice dictionary is also put back into its sync.Pool. +func PutZlibReader(z ZLibReader) { + z.Reader.Close() + PutByteSlice(z.dict) + zlibReader.Put(z) +} + +// GetZlibWriter returns a *zlib.Writer that is managed by a sync.Pool. +// Returns a writer that is resetted with w and ready for use. +// +// After use, the *zlib.Writer should be put back into the sync.Pool +// by calling PutZlibWriter. +func GetZlibWriter(w io.Writer) *zlib.Writer { + z := zlibWriter.Get().(*zlib.Writer) + z.Reset(w) + return z +} + +// PutZlibWriter puts w back into its sync.Pool. +func PutZlibWriter(w *zlib.Writer) { + zlibWriter.Put(w) +} |