mostynb / go-grpc-compression Goto Github PK
View Code? Open in Web Editor NEWgo gRPC encoding wrappers for some useful compression algorithms that are not available in google.golang.org/grpc
License: Apache License 2.0
go gRPC encoding wrappers for some useful compression algorithms that are not available in google.golang.org/grpc
License: Apache License 2.0
Just a note concerning how this library could be extended to support thread-safe configuration of compression settings.
For our project we needed this specifically for Zstd, and I used the following approach.
This allows us to configure up to 10 distinct encoder settings in a thread-safe way. I opened this issue to share the idea for consideration.
Hey there!
I noticed that this library doesn't use the snappy library from klauspost/compress, but it does import this library for zstd.
A cursory look makes it appear to be faster. Is there a reason why you aren't using it? Is it worth a PR?
i notice you replace zstd.Write to zstd.EncodeAll but without performance compare in 5f24893.
i implement different type of zstd encoding and benchmark it.
1, zstd-stream.
package main
import (
"bytes"
"io"
"os"
"runtime"
"sync"
"github.com/klauspost/compress/zstd"
_ "github.com/mostynb/go-grpc-compression/nonclobbering/zstd"
"google.golang.org/grpc/encoding"
)
// Name is the name registered for the gzip compressor.
const Name = "zstd-stream"
func init() {
c := &compressor{}
c.poolDecompressor.New = func() interface{} {
zr, _ := zstd.NewReader(nil)
runtime.SetFinalizer(zr, (*zstd.Decoder).Close)
return &reader{
Reader: zr,
pool: &c.poolDecompressor,
}
}
c.poolCompressor.New = func() interface{} {
zw, _ := zstd.NewWriter(nil)
runtime.SetFinalizer(zw, (*zstd.Encoder).Close)
return &writer{
Writer: zw,
pool: &c.poolCompressor,
}
}
encoding.RegisterCompressor(c)
}
type writer struct {
Writer *zstd.Encoder
pool *sync.Pool
}
func (c *compressor) Compress(w io.Writer) (io.WriteCloser, error) {
z := c.poolCompressor.Get().(*writer)
z.Writer.Reset(w)
return z, nil
}
func (z *writer) Close() error {
defer z.pool.Put(z)
return z.Writer.Close()
}
func (z *writer) Write(data []byte) (int, error) {
return z.Writer.Write(data)
}
type reader struct {
Reader *zstd.Decoder
pool *sync.Pool
}
func (c *compressor) Decompress(r io.Reader) (io.Reader, error) {
z := c.poolDecompressor.Get().(*reader)
if err := z.Reader.Reset(r); err != nil {
c.poolDecompressor.Put(z)
return nil, err
}
return z, nil
}
func (z *reader) Read(p []byte) (n int, err error) {
n, err = z.Reader.Read(p)
if err == io.EOF {
z.pool.Put(z)
}
return n, err
}
func (c *compressor) Name() string {
return Name
}
type compressor struct {
poolCompressor sync.Pool
poolDecompressor sync.Pool
}
2, zstd.
use current package.
func main() {
data, err := os.ReadFile("testdata/test.json")
if err != nil {
panic(err)
}
compress := func() []byte {
var buf = bytes.Buffer{}
c := encoding.GetCompressor("zstd-pool")
w, _ := c.Compress(&buf)
_, err = w.Write(data)
err = w.Close()
return buf.Bytes()
}
for i := 0; i < 10000; i++ {
compress()
}
}
use linux time command to execute the program.
zstd-stream:
real 0m12.891s
user 0m14.182s
sys 0m0.111s
zstd:
real 0m17.284s
user 0m17.298s
sys 0m0.082s
func main() {
data, err := os.ReadFile("testdata/test.json")
if err != nil {
panic(err)
}
compress := func() []byte {
var buf = bytes.Buffer{}
c := encoding.GetCompressor("zstd")
w, _ := c.Compress(&buf)
_, err = w.Write(data)
err = w.Close()
return buf.Bytes()
}
compressed := compress()
decompress := func() {
c := encoding.GetCompressor("zstd-stream")
r, err := c.Decompress(bytes.NewReader(compressed))
if err != nil {
panic(err)
}
_, err = io.ReadAll(r)
if err != nil {
panic(err)
}
}
for i := 0; i < 100000; i++ {
decompress()
}
}
use linux time command to execute the program.
zstd-stream:
real 0m34.640s
user 0m40.313s
sys 0m1.434s
zstd:
real 0m35.556s
user 0m37.684s
sys 0m0.803s
test file is from:
https://github.com/klauspost/compress/blob/master/gzip/testdata/test.json
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.