From 4f3335aac752ce779d8485299d187e23f75ae11a Mon Sep 17 00:00:00 2001 From: Tyler Bunnell Date: Fri, 11 Sep 2015 16:23:57 -0600 Subject: [PATCH] Add sync.Pool to gzip middleware --- middleware/compress.go | 16 ++++++++++++++-- middleware/compress_test.go | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/middleware/compress.go b/middleware/compress.go index eba2c7c4..8c009555 100644 --- a/middleware/compress.go +++ b/middleware/compress.go @@ -4,9 +4,11 @@ import ( "bufio" "compress/gzip" "io" + "io/ioutil" "net" "net/http" "strings" + "sync" "github.com/labstack/echo" ) @@ -37,6 +39,12 @@ func (w *gzipWriter) CloseNotify() <-chan bool { return w.ResponseWriter.(http.CloseNotifier).CloseNotify() } +var writerPool = sync.Pool{ + New: func() interface{} { + return gzip.NewWriter(ioutil.Discard) + }, +} + // Gzip returns a middleware which compresses HTTP response using gzip compression // scheme. func Gzip() echo.MiddlewareFunc { @@ -46,8 +54,12 @@ func Gzip() echo.MiddlewareFunc { return func(c *echo.Context) error { c.Response().Header().Add(echo.Vary, echo.AcceptEncoding) if strings.Contains(c.Request().Header.Get(echo.AcceptEncoding), scheme) { - w := gzip.NewWriter(c.Response().Writer()) - defer w.Close() + w := writerPool.Get().(*gzip.Writer) + w.Reset(c.Response().Writer()) + defer func() { + w.Close() + writerPool.Put(w) + }() gw := gzipWriter{Writer: w, ResponseWriter: c.Response().Writer()} c.Response().Header().Set(echo.ContentEncoding, scheme) c.Response().SetWriter(gw) diff --git a/middleware/compress_test.go b/middleware/compress_test.go index 85cc9ca2..fc727068 100644 --- a/middleware/compress_test.go +++ b/middleware/compress_test.go @@ -119,3 +119,25 @@ func TestGzipCloseNotify(t *testing.T) { assert.Equal(t, closed, true) } + +func BenchmarkGzip(b *testing.B) { + + b.StopTimer() + b.ReportAllocs() + + h := func(c *echo.Context) error { + c.Response().Write([]byte("test")) // For Content-Type sniffing + return nil + } + req, _ := http.NewRequest(echo.GET, "/", nil) + req.Header.Set(echo.AcceptEncoding, "gzip") + + b.StartTimer() + + for i := 0; i < b.N; i++ { + rec := httptest.NewRecorder() + c := echo.NewContext(req, echo.NewResponse(rec), echo.New()) + Gzip()(h)(c) + } + +}