Skip to content

Commit

Permalink
performance optimizations (#2947)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ReneWerner87 authored Apr 5, 2024
1 parent 6a7f015 commit c8c51ee
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 55 deletions.
62 changes: 52 additions & 10 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++ {
Expand Down Expand Up @@ -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)
}
})
}
53 changes: 9 additions & 44 deletions ctx_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down Expand Up @@ -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: "",
}
}

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c8c51ee

Please sign in to comment.