Skip to content

Instantly share code, notes, and snippets.

@gus3inov
Created May 21, 2025 10:08
Show Gist options
  • Save gus3inov/4541693fd693145f2144968c22cf8ac6 to your computer and use it in GitHub Desktop.
Save gus3inov/4541693fd693145f2144968c22cf8ac6 to your computer and use it in GitHub Desktop.
Efficient gzip decompression benchmark
package benchgzip
import (
"bytes"
"compress/gzip"
"io"
"sync"
"testing"
)
var (
// our sample: 50 KB of the letter 'a'
sampleData []byte
compressedData []byte
// pool for gzip.Reader
gzipReaderPool = sync.Pool{
New: func() interface{} {
return new(gzip.Reader)
},
}
// pool for bytes.Buffer
bufferPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
)
func init() {
// build sampleData and compress once
sampleData = bytes.Repeat([]byte("a"), 50*1024) // 50 KB
var buf bytes.Buffer
gw := gzip.NewWriter(&buf)
gw.Write(sampleData)
gw.Close()
compressedData = buf.Bytes()
}
func decompressSimple(data []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
defer r.Close()
return io.ReadAll(r)
}
func decompressPooled(data []byte) ([]byte, error) {
byteReader := bytes.NewReader(data)
// get and reset gzip.Reader
gr := gzipReaderPool.Get().(*gzip.Reader)
if err := gr.Reset(byteReader); err != nil {
gzipReaderPool.Put(gr)
return nil, err
}
// once done, Close and put back in pool
defer func() {
gr.Close()
gzipReaderPool.Put(gr)
}()
// get and reset buffer
buf := bufferPool.Get().(*bytes.Buffer)
buf.Reset()
// copy decompressed data into it
if _, err := io.Copy(buf, gr); err != nil {
bufferPool.Put(buf)
return nil, err
}
// copy out so our buffer can be reused
out := make([]byte, buf.Len())
copy(out, buf.Bytes())
bufferPool.Put(buf)
return out, nil
}
func BenchmarkDecompressSimple(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if _, err := decompressSimple(compressedData); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkDecompressPooled(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if _, err := decompressPooled(compressedData); err != nil {
b.Fatal(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment