Skip to content

Commit

Permalink
feat: improve warpf and warph function performance
Browse files Browse the repository at this point in the history
  • Loading branch information
tigerwill90 committed Dec 31, 2024
1 parent d67a4d0 commit 170e7c7
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
31 changes: 27 additions & 4 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,30 @@ func (c *cTx) Params() iter.Seq[Param] {

// Param retrieve a matching wildcard segment by name.
func (c *cTx) Param(name string) string {
for p := range c.Params() {
if p.Key == name {
return p.Value
if c.tsr {
for i := range *c.tsrParams {
if (*c.tsrParams)[i].Key == name {
return (*c.tsrParams)[i].Value
}
}
return ""
}

for i := range *c.params {
if (*c.params)[i].Key == name {
return (*c.params)[i].Value
}
}
return ""
}

func (c *cTx) ParamsLen() int {
if c.tsr {
return len(*c.tsrParams)
}
return len(*c.params)
}

// Path returns the request URL path.
func (c *cTx) Path() string {
return c.req.URL.Path
Expand Down Expand Up @@ -402,7 +418,14 @@ func (c *cTx) getQueries() url.Values {
// The route parameters are being accessed by the wrapped handler through the context.
func WrapF(f http.HandlerFunc) HandlerFunc {
return func(c Context) {
var params Params = slices.Collect(c.Params())

var params Params
if ps, ok := c.(interface{ ParamsLen() int }); ok {
params = make(Params, 0, ps.ParamsLen())
params = slices.AppendSeq(params, c.Params())
} else {
params = slices.Collect(c.Params())
}
if len(params) > 0 {
ctx := context.WithValue(c.Request().Context(), paramsKey, params)
f.ServeHTTP(c.Writer(), c.Request().WithContext(ctx))
Expand Down
19 changes: 19 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,22 @@ func TestWrapH(t *testing.T) {
})
}
}

// BenchmarkWrapF-16 2211204 559.8 ns/op 696 B/op 10 allocs/op
func BenchmarkWrapF(b *testing.B) {
req := httptest.NewRequest(http.MethodGet, "https://example.com/a/b/c", nil)
w := httptest.NewRecorder()

f := New()
f.MustHandle(http.MethodGet, "/{a}/{b}/{c}", WrapF(func(w http.ResponseWriter, r *http.Request) {

}))

b.ResetTimer()
b.ReportAllocs()

for range b.N {
f.ServeHTTP(w, req)
}

}
5 changes: 5 additions & 0 deletions txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ func (txn *Txn) Delete(method, pattern string) error {
return nil
}

// Truncate remove all routes for the provided methods. If not methods are provided,
// all routes are truncated.
func (txn *Txn) Truncate(methods ...string) error {
if txn.rootTxn == nil {
panic(ErrSettledTxn)
Expand Down Expand Up @@ -228,6 +230,9 @@ func (txn *Txn) Iter() Iter {

// Len returns the number of registered route.
func (txn *Txn) Len() int {
if txn.rootTxn == nil {
panic(ErrSettledTxn)
}
return txn.rootTxn.size
}

Expand Down

0 comments on commit 170e7c7

Please sign in to comment.