perf: improve gzip performance with sync.pool (#1321)

Signed-off-by: rfyiamcool <rfyiamcool@163.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
This commit is contained in:
fengyun.rui
2023-11-10 22:02:02 +08:00
committed by GitHub
parent 8e0cb6dc47
commit a580c15f6a
4 changed files with 155 additions and 3 deletions
+45
View File
@@ -17,14 +17,23 @@ package msggateway
import (
"bytes"
"compress/gzip"
"errors"
"io"
"sync"
"github.com/OpenIMSDK/tools/utils"
)
var (
gzipWriterPool = sync.Pool{New: func() any { return gzip.NewWriter(nil) }}
gzipReaderPool = sync.Pool{New: func() any { return new(gzip.Reader) }}
)
type Compressor interface {
Compress(rawData []byte) ([]byte, error)
CompressWithPool(rawData []byte) ([]byte, error)
DeCompress(compressedData []byte) ([]byte, error)
DecompressWithPool(compressedData []byte) ([]byte, error)
}
type GzipCompressor struct {
compressProtocol string
@@ -46,6 +55,22 @@ func (g *GzipCompressor) Compress(rawData []byte) ([]byte, error) {
return gzipBuffer.Bytes(), nil
}
func (g *GzipCompressor) CompressWithPool(rawData []byte) ([]byte, error) {
gz := gzipWriterPool.Get().(*gzip.Writer)
defer gzipWriterPool.Put(gz)
gzipBuffer := bytes.Buffer{}
gz.Reset(&gzipBuffer)
if _, err := gz.Write(rawData); err != nil {
return nil, utils.Wrap(err, "")
}
if err := gz.Close(); err != nil {
return nil, utils.Wrap(err, "")
}
return gzipBuffer.Bytes(), nil
}
func (g *GzipCompressor) DeCompress(compressedData []byte) ([]byte, error) {
buff := bytes.NewBuffer(compressedData)
reader, err := gzip.NewReader(buff)
@@ -59,3 +84,23 @@ func (g *GzipCompressor) DeCompress(compressedData []byte) ([]byte, error) {
_ = reader.Close()
return compressedData, nil
}
func (g *GzipCompressor) DecompressWithPool(compressedData []byte) ([]byte, error) {
reader := gzipReaderPool.Get().(*gzip.Reader)
if reader == nil {
return nil, errors.New("NewReader failed")
}
defer gzipReaderPool.Put(reader)
err := reader.Reset(bytes.NewReader(compressedData))
if err != nil {
return nil, utils.Wrap(err, "NewReader failed")
}
compressedData, err = io.ReadAll(reader)
if err != nil {
return nil, utils.Wrap(err, "ReadAll failed")
}
_ = reader.Close()
return compressedData, nil
}