From b6f4ee6bc8e7416430f7eb5926dff5d7a5133424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Wed, 25 Mar 2026 22:41:22 +0100 Subject: [PATCH 1/3] test: add benchmarks for deflate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- filters/builtin/compress_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/filters/builtin/compress_test.go b/filters/builtin/compress_test.go index b1c034ac62..5578966028 100644 --- a/filters/builtin/compress_test.go +++ b/filters/builtin/compress_test.go @@ -774,6 +774,12 @@ func TestPoolRelease(t *testing.T) { wg.Wait() } +func BenchmarkCompressDeflate0(b *testing.B) { benchmarkCompress(b, 0, []string{"deflate"}) } +func BenchmarkCompressDeflate2(b *testing.B) { benchmarkCompress(b, 100, []string{"deflate"}) } +func BenchmarkCompressDeflate4(b *testing.B) { benchmarkCompress(b, 10000, []string{"deflate"}) } +func BenchmarkCompressDeflate6(b *testing.B) { benchmarkCompress(b, 1000000, []string{"deflate"}) } +func BenchmarkCompressDeflate8(b *testing.B) { benchmarkCompress(b, 100000000, []string{"deflate"}) } + func BenchmarkCompressGzip0(b *testing.B) { benchmarkCompress(b, 0, []string{"gzip,deflate"}) } func BenchmarkCompressGzip2(b *testing.B) { benchmarkCompress(b, 100, []string{"gzip,deflate"}) } func BenchmarkCompressGzip4(b *testing.B) { benchmarkCompress(b, 10000, []string{"gzip,deflate"}) } From 4f1f28147918d0c44feb2e54f0148c71e02b8325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Wed, 25 Mar 2026 22:59:22 +0100 Subject: [PATCH 2/3] optimize: deflate and gzip compression by leveraging an optimized library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit goos: linux goarch: amd64 pkg: github.com/zalando/skipper/filters/builtin cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ CompressDeflate0 18.52µ ± 59% 18.03µ ± 56% -2.60% (p=0.029 n=10) CompressDeflate0-2 11.00µ ± 3% 11.40µ ± 9% ~ (p=0.075 n=10) CompressDeflate0-4 6.405µ ± 1% 7.122µ ± 1% +11.19% (p=0.000 n=10) CompressDeflate0-8 4.675µ ± 3% 5.072µ ± 8% +8.48% (p=0.000 n=10) CompressDeflate0-16 3.989µ ± 2% 4.465µ ± 2% +11.92% (p=0.000 n=10) CompressDeflate2 33.31µ ± 1% 29.30µ ± 1% -12.04% (p=0.000 n=10) CompressDeflate2-2 18.60µ ± 2% 17.99µ ± 3% -3.26% (p=0.004 n=10) CompressDeflate2-4 11.18µ ± 2% 11.06µ ± 1% ~ (p=0.075 n=10) CompressDeflate2-8 7.796µ ± 3% 7.761µ ± 5% ~ (p=0.494 n=10) CompressDeflate2-16 6.361µ ± 1% 6.457µ ± 1% +1.51% (p=0.004 n=10) CompressDeflate4 156.39µ ± 3% 56.42µ ± 3% -63.92% (p=0.000 n=10) CompressDeflate4-2 85.19µ ± 1% 36.27µ ± 2% -57.43% (p=0.000 n=10) CompressDeflate4-4 50.89µ ± 3% 23.32µ ± 8% -54.18% (p=0.000 n=10) CompressDeflate4-8 33.67µ ± 1% 16.10µ ± 1% -52.20% (p=0.000 n=10) CompressDeflate4-16 32.91µ ± 14% 14.07µ ± 6% -57.25% (p=0.000 n=10) CompressDeflate6 10.321m ± 1% 2.549m ± 1% -75.30% (p=0.000 n=10) CompressDeflate6-2 5.948m ± 2% 1.776m ± 7% -70.15% (p=0.000 n=10) CompressDeflate6-4 3.564m ± 2% 1.145m ± 2% -67.87% (p=0.000 n=10) CompressDeflate6-8 2410.7µ ± 2% 796.2µ ± 1% -66.97% (p=0.000 n=10) CompressDeflate6-16 2032.4µ ± 1% 713.4µ ± 3% -64.90% (p=0.000 n=10) CompressDeflate8 1006.1m ± 8% 215.3m ± 5% -78.60% (p=0.000 n=10) CompressDeflate8-2 1033.0m ± 6% 138.9m ± 6% -86.55% (p=0.000 n=10) CompressDeflate8-4 1057.8m ± 3% 103.0m ± 12% -90.26% (p=0.000 n=10) CompressDeflate8-8 1062.16m ± 2% 70.81m ± 11% -93.33% (p=0.000 n=10) CompressDeflate8-16 1085.24m ± 6% 75.88m ± 4% -93.01% (p=0.000 n=10) geomean 475.6µ 203.4µ -57.24% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ CompressDeflate0 15.80Ki ± 0% 15.80Ki ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate0-2 16.36Ki ± 0% 16.21Ki ± 0% -0.95% (p=0.000 n=10) CompressDeflate0-4 17.51Ki ± 0% 17.12Ki ± 0% -2.19% (p=0.000 n=10) CompressDeflate0-8 18.77Ki ± 1% 18.34Ki ± 1% -2.30% (p=0.000 n=10) CompressDeflate0-16 18.62Ki ± 1% 18.04Ki ± 1% -3.11% (p=0.000 n=10) CompressDeflate2 15.80Ki ± 0% 15.80Ki ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2-2 16.53Ki ± 1% 16.38Ki ± 0% -0.90% (p=0.006 n=10) CompressDeflate2-4 17.90Ki ± 1% 17.57Ki ± 1% -1.87% (p=0.000 n=10) CompressDeflate2-8 19.18Ki ± 1% 18.71Ki ± 1% -2.45% (p=0.000 n=10) CompressDeflate2-16 20.37Ki ± 1% 19.64Ki ± 1% -3.59% (p=0.000 n=10) CompressDeflate4 39.18Ki ± 0% 39.18Ki ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4-2 40.17Ki ± 1% 40.41Ki ± 0% +0.60% (p=0.002 n=10) CompressDeflate4-4 41.84Ki ± 1% 42.46Ki ± 1% +1.50% (p=0.002 n=10) CompressDeflate4-8 42.46Ki ± 1% 44.73Ki ± 1% +5.33% (p=0.000 n=10) CompressDeflate4-16 42.03Ki ± 1% 44.98Ki ± 1% +7.00% (p=0.000 n=10) CompressDeflate6 2.101Mi ± 0% 2.101Mi ± 0% +0.00% (p=0.012 n=10) CompressDeflate6-2 2.136Mi ± 2% 2.131Mi ± 0% ~ (p=0.579 n=10) CompressDeflate6-4 2.166Mi ± 1% 2.187Mi ± 1% +0.99% (p=0.007 n=10) CompressDeflate6-8 2.179Mi ± 1% 2.215Mi ± 0% +1.66% (p=0.000 n=10) CompressDeflate6-16 2.204Mi ± 1% 2.184Mi ± 0% -0.94% (p=0.005 n=10) CompressDeflate8 236.0Mi ± 0% 236.0Mi ± 0% -0.00% (p=0.002 n=10) CompressDeflate8-2 237.1Mi ± 0% 236.5Mi ± 0% -0.27% (p=0.001 n=10) CompressDeflate8-4 237.1Mi ± 0% 236.4Mi ± 0% ~ (p=0.138 n=10) CompressDeflate8-8 237.2Mi ± 0% 236.6Mi ± 0% -0.24% (p=0.002 n=10) CompressDeflate8-16 237.2Mi ± 0% 236.7Mi ± 0% -0.18% (p=0.000 n=10) geomean 369.0Ki 368.6Ki -0.12% ¹ all samples are equal │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ CompressDeflate0 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate0-2 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate0-4 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate0-8 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate0-16 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2-2 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2-4 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2-8 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate2-16 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4 34.00 ± 0% 34.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4-2 34.00 ± 0% 34.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4-4 34.00 ± 0% 34.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4-8 34.00 ± 0% 34.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate4-16 34.00 ± 0% 34.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate6 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate6-2 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) CompressDeflate6-4 48.00 ± 0% 49.00 ± 0% +2.08% (p=0.000 n=10) CompressDeflate6-8 48.00 ± 0% 49.00 ± 0% +2.08% (p=0.000 n=10) CompressDeflate6-16 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) ¹ CompressDeflate8 71.00 ± 28% 63.00 ± 5% -11.27% (p=0.000 n=10) CompressDeflate8-2 94.50 ± 8% 71.50 ± 3% -24.34% (p=0.000 n=10) CompressDeflate8-4 99.00 ± 17% 69.00 ± 3% -30.30% (p=0.000 n=10) CompressDeflate8-8 112.50 ± 5% 71.50 ± 3% -36.44% (p=0.000 n=10) CompressDeflate8-16 128.50 ± 3% 75.00 ± 3% -41.63% (p=0.000 n=10) geomean 39.26 36.66 -6.61% ¹ all samples are equal Signed-off-by: Sandor Szücs --- filters/builtin/compress.go | 6 ++++-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/filters/builtin/compress.go b/filters/builtin/compress.go index 72a8a80a0d..0b33163aa2 100644 --- a/filters/builtin/compress.go +++ b/filters/builtin/compress.go @@ -13,6 +13,8 @@ import ( "sync" "github.com/andybalholm/brotli" + kpflate "github.com/klauspost/compress/flate" + kpgzip "github.com/klauspost/compress/gzip" log "github.com/sirupsen/logrus" "github.com/zalando/skipper/filters" @@ -342,12 +344,12 @@ func newEncoder(enc string, level int) (encoder, error) { if level > gzip.BestCompression { level = gzip.BestCompression } - return gzip.NewWriterLevel(nil, level) + return kpgzip.NewWriterLevel(nil, level) case "deflate": if level > flate.BestCompression { level = flate.BestCompression } - return flate.NewWriter(nil, level) + return kpflate.NewWriter(nil, level) default: unsupported() return nil, nil diff --git a/go.mod b/go.mod index ce8fe3f266..830353f13e 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/google/uuid v1.6.0 github.com/hashicorp/memberlist v0.5.4 github.com/instana/go-sensor v1.73.1 + github.com/klauspost/compress v1.18.5 github.com/lightstep/lightstep-tracer-go v0.26.0 github.com/miekg/dns v1.1.72 github.com/oklog/ulid v1.3.1 @@ -195,7 +196,6 @@ require ( github.com/itchyny/timefmt-go v0.1.7 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.18.2 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect diff --git a/go.sum b/go.sum index 7dc1e1f571..87c5fde31f 100644 --- a/go.sum +++ b/go.sum @@ -418,8 +418,8 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= -github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= From 0762b28bcb9c5bed620bad7676dbf2a130ab49b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Thu, 26 Mar 2026 08:34:06 +0100 Subject: [PATCH 3/3] copied from https://github.com/zalando/skipper/pull/3933 by @ivan-digital MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- filters/builtin/compress_test.go | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/filters/builtin/compress_test.go b/filters/builtin/compress_test.go index 5578966028..f6e901e726 100644 --- a/filters/builtin/compress_test.go +++ b/filters/builtin/compress_test.go @@ -792,6 +792,70 @@ func BenchmarkCompressBrotli4(b *testing.B) { benchmarkCompress(b, 10000, []stri func BenchmarkCompressBrotli6(b *testing.B) { benchmarkCompress(b, 1000000, []string{"br"}) } func BenchmarkCompressBrotli8(b *testing.B) { benchmarkCompress(b, 100000000, []string{"br"}) } +func benchmarkCompressJSON(b *testing.B, n int64, encoding []string) { + // Repeating JSON pattern — highly compressible, realistic payload + pattern := []byte(`{"id":12345,"name":"test-user","email":"user@example.com","active":true,"tags":["a","b"]},`) + buf := make([]byte, n) + for i := 0; i < len(buf); i += len(pattern) { + copy(buf[i:], pattern) + } + + s := NewCompress() + f, _ := s.CreateFilter(nil) + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + body := io.NopCloser(bytes.NewReader(buf)) + req := &http.Request{Header: http.Header{"Accept-Encoding": encoding}} + rsp := &http.Response{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: body} + ctx := &filtertest.Context{ + FRequest: req, + FResponse: rsp} + f.Response(ctx) + _, err := io.ReadAll(rsp.Body) + if err != nil { + b.Fatal(err) + } + } + }) +} + +func benchmarkCompressLevel(b *testing.B, n int64, level int, encoding []string) { + s := NewCompress() + f, _ := s.CreateFilter([]any{float64(level)}) + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + body := io.NopCloser(&io.LimitedReader{R: rand.New(rand.NewSource(0)), N: n}) + req := &http.Request{Header: http.Header{"Accept-Encoding": encoding}} + rsp := &http.Response{ + Header: http.Header{"Content-Type": []string{"application/octet-stream"}}, + Body: body} + ctx := &filtertest.Context{ + FRequest: req, + FResponse: rsp} + f.Response(ctx) + _, err := io.ReadAll(rsp.Body) + if err != nil { + b.Fatal(err) + } + } + }) +} + +// JSON payload benchmarks (compressible data) +func BenchmarkCompressGzipJSON4(b *testing.B) { benchmarkCompressJSON(b, 10000, []string{"gzip"}) } +func BenchmarkCompressGzipJSON6(b *testing.B) { benchmarkCompressJSON(b, 1000000, []string{"gzip"}) } +func BenchmarkCompressGzipJSON8(b *testing.B) { benchmarkCompressJSON(b, 100000000, []string{"gzip"}) } + +// Higher compression level (level 6 = DefaultCompression) +func BenchmarkCompressGzipLevel6_4(b *testing.B) { + benchmarkCompressLevel(b, 10000, 6, []string{"gzip"}) +} +func BenchmarkCompressGzipLevel6_6(b *testing.B) { + benchmarkCompressLevel(b, 1000000, 6, []string{"gzip"}) +} + func BenchmarkCanEncodeEntity(b *testing.B) { testCases := []struct { name string