performance optimizations (#2947)

* performance optimizations

* add a new benchmark that tests the simple flow
this will be used to make differences between version 2 and 3 directly visible

* remove redundant ctx.Reset call

* Add a new benchmark that tests the ctx acquire and release flow
this will be used to show differences between version 2 and 3 directly

* Add a new benchmark that tests the ctx acquire and release flow
this will be used to show differences between version 2 and 3 directly
pull/2957/head
RW 2024-04-05 08:29:39 +02:00 committed by GitHub
parent 6a7f015897
commit c8c51ee783
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 55 deletions

View File

@ -1408,16 +1408,6 @@ func Test_App_Next_Method(t *testing.T) {
require.Equal(t, 404, resp.StatusCode, "Status code")
}
// go test -v -run=^$ -bench=Benchmark_AcquireCtx -benchmem -count=4
func Benchmark_AcquireCtx(b *testing.B) {
app := New()
for n := 0; n < b.N; n++ {
c := app.AcquireCtx(&fasthttp.RequestCtx{})
app.ReleaseCtx(c)
}
}
// go test -v -run=^$ -bench=Benchmark_NewError -benchmem -count=4
func Benchmark_NewError(b *testing.B) {
for n := 0; n < b.N; n++ {
@ -1975,3 +1965,55 @@ func Test_Route_Naming_Issue_2671_2685(t *testing.T) {
sRoute2 := app.GetRoute("simple-route2")
require.Equal(t, "/simple-route", sRoute2.Path)
}
// go test -v -run=^$ -bench=Benchmark_Communication_Flow -benchmem -count=4
func Benchmark_Communication_Flow(b *testing.B) {
app := New()
app.Get("/", func(c Ctx) error {
return c.SendString("Hello, World!")
})
h := app.Handler()
fctx := &fasthttp.RequestCtx{}
fctx.Request.Header.SetMethod(MethodGet)
fctx.Request.SetRequestURI("/")
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
h(fctx)
}
require.Equal(b, 200, fctx.Response.Header.StatusCode())
require.Equal(b, "Hello, World!", string(fctx.Response.Body()))
}
// go test -v -run=^$ -bench=Benchmark_Ctx_AcquireReleaseFlow -benchmem -count=4
func Benchmark_Ctx_AcquireReleaseFlow(b *testing.B) {
app := New()
fctx := &fasthttp.RequestCtx{}
b.Run("withoutRequestCtx", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
c, _ := app.AcquireCtx(fctx).(*DefaultCtx) //nolint:errcheck // not needed
app.ReleaseCtx(c)
}
})
b.Run("withRequestCtx", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
c, _ := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck // not needed
app.ReleaseCtx(c)
}
})
}

View File

@ -375,9 +375,6 @@ type Ctx interface {
// ClientHelloInfo return CHI from context
ClientHelloInfo() *tls.ClientHelloInfo
// SetReq resets fields of context that is relating to request.
setReq(fctx *fasthttp.RequestCtx)
// Release is a method to reset context fields when to use ReleaseCtx()
release()
}
@ -407,16 +404,6 @@ func NewDefaultCtx(app *App) *DefaultCtx {
return &DefaultCtx{
// Set app reference
app: app,
// Reset route and handler index
indexRoute: -1,
indexHandler: 0,
// Reset matched flag
matched: false,
// reset base uri
baseURI: "",
}
}
@ -452,32 +439,26 @@ func (app *App) ReleaseCtx(c Ctx) {
// Reset is a method to reset context fields by given request when to use server handlers.
func (c *DefaultCtx) Reset(fctx *fasthttp.RequestCtx) {
// Reset route and handler index
c.indexRoute = -1
c.indexHandler = 0
// Reset matched flag
c.matched = false
// Set paths
c.pathOriginal = c.app.getString(fctx.URI().PathOriginal())
// Attach *fasthttp.RequestCtx to ctx
c.setReq(fctx)
// Set method
c.method = c.app.getString(fctx.Request.Header.Method())
c.methodINT = c.app.methodInt(c.method)
// Attach *fasthttp.RequestCtx to ctx
c.fasthttp = fctx
// reset base uri
c.baseURI = ""
// Prettify path
c.configDependentPaths()
}
// Release is a method to reset context fields when to use ReleaseCtx()
func (c *DefaultCtx) release() {
// Reset route and handler index
c.indexRoute = -1
c.indexHandler = 0
// Reset matched flag
c.matched = false
// reset base uri
c.baseURI = ""
c.route = nil
c.fasthttp = nil
c.bind = nil
@ -489,22 +470,6 @@ func (c *DefaultCtx) release() {
}
}
// SetReq resets fields of context that is relating to request.
func (c *DefaultCtx) setReq(fctx *fasthttp.RequestCtx) {
// Set paths
c.pathOriginal = c.app.getString(fctx.URI().PathOriginal())
// Attach *fasthttp.RequestCtx to ctx
c.fasthttp = fctx
// Set method
c.method = c.app.getString(fctx.Request.Header.Method())
c.methodINT = c.app.methodInt(c.method)
// Prettify path
c.configDependentPaths()
}
// Methods to use with next stack.
func (c *DefaultCtx) getMethodINT() int {
return c.methodINT

View File

@ -218,7 +218,6 @@ func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
panic(errors.New("requestHandler: failed to type-assert to *DefaultCtx"))
}
}
c.Reset(rctx)
defer app.ReleaseCtx(c)
// handle invalid http method directly