From 63a90dd8dd0b1edc0fa5002f9ce137ff10b2a9a2 Mon Sep 17 00:00:00 2001 From: TangYang Date: Tue, 14 May 2024 09:01:10 +0000 Subject: [PATCH 1/3] feat: add intel/fastgo compression option Signed-off-by: TangYang --- go.mod | 1 + go.sum | 4 +++ pkg/common/compress/compress.go | 54 ++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 3619b833d..efbe26a3e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/bytedance/sonic v1.8.1 github.com/cloudwego/netpoll v0.5.0 github.com/fsnotify/fsnotify v1.5.4 + github.com/intel/fastgo v1.0.0 github.com/tidwall/gjson v1.14.4 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220412211240-33da011f77ad diff --git a/go.sum b/go.sum index 3cf3c2f96..e66b3517e 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,10 @@ github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQy github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 h1:yE9ULgp02BhYIrO6sdV/FPe0xQM6fNHkVQW2IAymfM0= github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ= +github.com/intel/fastgo v0.0.0-20240326175205-0352400733f3 h1:eEsgV+WoiMJxGG2N9eAxI84oTNLthoy89ALRqKvyWcU= +github.com/intel/fastgo v0.0.0-20240326175205-0352400733f3/go.mod h1:pIC/1aq2eXDAGL94kqGpKGdYgexgzArnqiixeDyiCg0= +github.com/intel/fastgo v1.0.0 h1:Nk/mUrJthg0tKXVC9CK6ssza8FBIHRHDl9DfjHWzd5U= +github.com/intel/fastgo v1.0.0/go.mod h1:pIC/1aq2eXDAGL94kqGpKGdYgexgzArnqiixeDyiCg0= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= diff --git a/pkg/common/compress/compress.go b/pkg/common/compress/compress.go index bbdd07b63..b3250ce4b 100644 --- a/pkg/common/compress/compress.go +++ b/pkg/common/compress/compress.go @@ -48,6 +48,9 @@ import ( "io" "sync" + "github.com/intel/fastgo" + igzip "github.com/intel/fastgo/compress/gzip" + "github.com/cloudwego/hertz/pkg/common/bytebufferpool" "github.com/cloudwego/hertz/pkg/common/stackless" "github.com/cloudwego/hertz/pkg/common/utils" @@ -56,7 +59,10 @@ import ( const CompressDefaultCompression = 6 // flate.DefaultCompression -var gzipReaderPool sync.Pool +var ( + readerPool sync.Pool + gzipReaderPool sync.Pool +) var ( stacklessGzipWriterPoolMap = newCompressWriterPoolMap() @@ -75,6 +81,13 @@ func newCompressWriterPoolMap() []*sync.Pool { return m } +type Writer = stackless.Writer + +type Reader interface { + Reset(io.Reader) error + io.ReadCloser +} + type compressCtx struct { w io.Writer p []byte @@ -101,13 +114,13 @@ func (w *byteSliceWriter) Write(p []byte) (int, error) { // bytes written to w. func WriteGunzip(w io.Writer, p []byte) (int, error) { r := &byteSliceReader{p} - zr, err := AcquireGzipReader(r) + zr, err := acquireGzipReader(r) if err != nil { return 0, err } zw := network.NewWriter(w) n, err := utils.CopyZeroAlloc(zw, zr) - ReleaseGzipReader(zr) + releaseGzipReader(zr) nn := int(n) if int64(nn) != n { return 0, fmt.Errorf("too much data gunzipped: %d", n) @@ -128,6 +141,27 @@ func (r *byteSliceReader) Read(p []byte) (int, error) { return n, nil } +func acquireGzipReader(r io.Reader) (Reader, error) { + v := readerPool.Get() + if v == nil { + if fastgo.Optimized() { + return igzip.NewReader(r) + } + + return gzip.NewReader(r) + } + zr := v.(Reader) + if err := zr.Reset(r); err != nil { + return nil, err + } + return zr, nil +} + +func releaseGzipReader(zr Reader) { + zr.Close() + readerPool.Put(zr) +} + func AcquireGzipReader(r io.Reader) (*gzip.Reader, error) { v := gzipReaderPool.Get() if v == nil { @@ -180,25 +214,31 @@ func nonblockingWriteGzip(ctxv interface{}) { releaseRealGzipWriter(zw, ctx.level) } -func releaseRealGzipWriter(zw *gzip.Writer, level int) { +func releaseRealGzipWriter(zw Writer, level int) { zw.Close() nLevel := normalizeCompressLevel(level) p := realGzipWriterPoolMap[nLevel] p.Put(zw) } -func acquireRealGzipWriter(w io.Writer, level int) *gzip.Writer { +func acquireRealGzipWriter(w io.Writer, level int) Writer { nLevel := normalizeCompressLevel(level) p := realGzipWriterPoolMap[nLevel] v := p.Get() if v == nil { - zw, err := gzip.NewWriterLevel(w, level) + var zw Writer + var err error + if fastgo.Optimized() && level <= 2 { + zw, err = igzip.NewWriterLevel(w, level) + } else { + zw, err = gzip.NewWriterLevel(w, level) + } if err != nil { panic(fmt.Sprintf("BUG: unexpected error from gzip.NewWriterLevel(%d): %s", level, err)) } return zw } - zw := v.(*gzip.Writer) + zw := v.(Writer) zw.Reset(w) return zw } From 533b7cce5000d526f2814c25d05c3fb0a70e8297 Mon Sep 17 00:00:00 2001 From: TangYang Date: Mon, 20 May 2024 07:29:48 +0000 Subject: [PATCH 2/3] Update FastGo version Signed-off-by: TangYang --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index efbe26a3e..76c63c9a3 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/bytedance/sonic v1.8.1 github.com/cloudwego/netpoll v0.5.0 github.com/fsnotify/fsnotify v1.5.4 - github.com/intel/fastgo v1.0.0 + github.com/intel/fastgo v1.0.1 github.com/tidwall/gjson v1.14.4 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220412211240-33da011f77ad diff --git a/go.sum b/go.sum index e66b3517e..223673d12 100644 --- a/go.sum +++ b/go.sum @@ -29,10 +29,8 @@ github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQy github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 h1:yE9ULgp02BhYIrO6sdV/FPe0xQM6fNHkVQW2IAymfM0= github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ= -github.com/intel/fastgo v0.0.0-20240326175205-0352400733f3 h1:eEsgV+WoiMJxGG2N9eAxI84oTNLthoy89ALRqKvyWcU= -github.com/intel/fastgo v0.0.0-20240326175205-0352400733f3/go.mod h1:pIC/1aq2eXDAGL94kqGpKGdYgexgzArnqiixeDyiCg0= -github.com/intel/fastgo v1.0.0 h1:Nk/mUrJthg0tKXVC9CK6ssza8FBIHRHDl9DfjHWzd5U= -github.com/intel/fastgo v1.0.0/go.mod h1:pIC/1aq2eXDAGL94kqGpKGdYgexgzArnqiixeDyiCg0= +github.com/intel/fastgo v1.0.1 h1:Bie0KlsOOuZ7j2cdqmPRHmtPgwoFG/y54J3+lWDxPMw= +github.com/intel/fastgo v1.0.1/go.mod h1:sctwebRi3SXzcojadNKwCgZgKy/Y/pSzSUR0aFF+cPg= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= From 206ff967c78320dde4e2d077052178f14cbb43bd Mon Sep 17 00:00:00 2001 From: TangYang Date: Tue, 28 May 2024 08:36:45 +0000 Subject: [PATCH 3/3] add HERTZ_EXP_FASTGO_ENABLE environment variable to enable fastgo comopression and decompression Signed-off-by: TangYang --- pkg/common/compress/compress.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/common/compress/compress.go b/pkg/common/compress/compress.go index b3250ce4b..31554884a 100644 --- a/pkg/common/compress/compress.go +++ b/pkg/common/compress/compress.go @@ -46,6 +46,8 @@ import ( "compress/gzip" "fmt" "io" + "os" + "strconv" "sync" "github.com/intel/fastgo" @@ -57,6 +59,14 @@ import ( "github.com/cloudwego/hertz/pkg/network" ) +var fastgoEnable bool + +func init() { + if fastgo.Optimized() { + fastgoEnable, _ = strconv.ParseBool(os.Getenv("HERTZ_EXP_FASTGO_ENABLE")) + } +} + const CompressDefaultCompression = 6 // flate.DefaultCompression var ( @@ -144,7 +154,7 @@ func (r *byteSliceReader) Read(p []byte) (int, error) { func acquireGzipReader(r io.Reader) (Reader, error) { v := readerPool.Get() if v == nil { - if fastgo.Optimized() { + if fastgoEnable { return igzip.NewReader(r) } @@ -228,7 +238,7 @@ func acquireRealGzipWriter(w io.Writer, level int) Writer { if v == nil { var zw Writer var err error - if fastgo.Optimized() && level <= 2 { + if fastgoEnable && level <= 2 { zw, err = igzip.NewWriterLevel(w, level) } else { zw, err = gzip.NewWriterLevel(w, level)