From e722d82206203186cc065f9b771d8a73f95a9e0a Mon Sep 17 00:00:00 2001 From: RW Date: Sun, 25 May 2025 17:23:03 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Performance=20optimization?= =?UTF-8?q?s=20(#3477)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adpater / HTTPHandler NEW Benchmark_HTTPHandler-12 1762837 640.6 ns/op 696 B/op 10 allocs/op Benchmark_HTTPHandler-12 1924524 616.5 ns/op 696 B/op 10 allocs/op Benchmark_HTTPHandler-12 1838780 650.4 ns/op 696 B/op 10 allocs/op Benchmark_HTTPHandler-12 1876947 644.0 ns/op 696 B/op 10 allocs/op OLD Benchmark_HTTPHandler-12 1864819 667.2 ns/op 720 B/op 11 allocs/op Benchmark_HTTPHandler-12 1892569 677.0 ns/op 720 B/op 11 allocs/op Benchmark_HTTPHandler-12 1811704 639.5 ns/op 720 B/op 11 allocs/op Benchmark_HTTPHandler-12 1879849 644.0 ns/op 720 B/op 11 allocs/op Utils / IsNoCache NEW Benchmark_Utils_IsNoCache-12 44307204 27.08 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 40782919 26.88 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 44228217 26.69 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 45605700 26.75 ns/op 0 B/op 0 allocs/op OLD Benchmark_Utils_IsNoCache-12 30043908 37.80 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 32137476 37.51 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 31474653 37.92 ns/op 0 B/op 0 allocs/op Benchmark_Utils_IsNoCache-12 31838683 37.71 ns/op 0 B/op 0 allocs/op --- helpers.go | 42 ++++++++++++++++-------------- middleware/adaptor/adaptor.go | 2 +- middleware/adaptor/adaptor_test.go | 31 ++++++++++++++++++++++ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/helpers.go b/helpers.go index e80e89c1..503ede73 100644 --- a/helpers.go +++ b/helpers.go @@ -603,28 +603,30 @@ const noCacheValue = "no-cache" // isNoCache checks if the cacheControl header value is a `no-cache`. func isNoCache(cacheControl string) bool { - i := strings.Index(cacheControl, noCacheValue) - if i == -1 { - return false + n := len(cacheControl) + ncLen := len(noCacheValue) + for i := 0; i < n; i++ { + if cacheControl[i] != 'n' { + continue + } + if i+ncLen > n { + return false + } + if cacheControl[i:i+ncLen] != noCacheValue { + continue + } + if i > 0 { + prev := cacheControl[i-1] + if prev != ' ' && prev != ',' { + continue + } + } + if i+ncLen == n || cacheControl[i+ncLen] == ',' { + return true + } } - // Xno-cache - if i > 0 && !(cacheControl[i-1] == ' ' || cacheControl[i-1] == ',') { - return false - } - - // bla bla, no-cache - if i+len(noCacheValue) == len(cacheControl) { - return true - } - - // bla bla, no-cacheX - if cacheControl[i+len(noCacheValue)] != ',' { - return false - } - - // OK - return true + return false } var errTestConnClosed = errors.New("testConn is closed") diff --git a/middleware/adaptor/adaptor.go b/middleware/adaptor/adaptor.go index 42b72101..7fe1fc20 100644 --- a/middleware/adaptor/adaptor.go +++ b/middleware/adaptor/adaptor.go @@ -32,8 +32,8 @@ func HTTPHandlerFunc(h http.HandlerFunc) fiber.Handler { // HTTPHandler wraps net/http handler to fiber handler func HTTPHandler(h http.Handler) fiber.Handler { + handler := fasthttpadaptor.NewFastHTTPHandler(h) return func(c fiber.Ctx) error { - handler := fasthttpadaptor.NewFastHTTPHandler(h) handler(c.RequestCtx()) return nil } diff --git a/middleware/adaptor/adaptor_test.go b/middleware/adaptor/adaptor_test.go index 7bede0a8..2340b7af 100644 --- a/middleware/adaptor/adaptor_test.go +++ b/middleware/adaptor/adaptor_test.go @@ -634,3 +634,34 @@ func Benchmark_FiberHandlerFunc_Parallel(b *testing.B) { }) } } + +func Benchmark_HTTPHandler(b *testing.B) { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) //nolint:errcheck // not needed + }) + + var err error + app := fiber.New() + + ctx := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer func() { + app.ReleaseCtx(ctx) + }() + + b.ReportAllocs() + b.ResetTimer() + + fiberHandler := HTTPHandler(handler) + + for i := 0; i < b.N; i++ { + ctx.Request().Reset() + ctx.Response().Reset() + ctx.Request().SetRequestURI("/test") + ctx.Request().Header.SetMethod("GET") + + err = fiberHandler(ctx) + } + + require.NoError(b, err) +}