diff options
author | Calvin Xiao <calvin325@gmail.com> | 2021-05-03 00:35:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-02 10:35:28 -0600 |
commit | 53ececda21f77d000ee893bc981d6ec5c33872f8 (patch) | |
tree | 527fad5c6f5a610f0031a2373695f44427b2168a | |
parent | 637fd8f67b7ff6191673ff13e94825a4ec896891 (diff) |
caddyhttp: performance improvement in HeaderRE Matcher (#4143)
Below is the report using `benchstat` and cmd:
`go test -run=BenchmarkHeaderREMatcher -bench=BenchmarkHeaderREMatcher -benchmem -count=10`
```
name old time/op new time/op delta
HeaderREMatcher-16 869ns ± 1% 658ns ± 0% -24.29% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
HeaderREMatcher-16 144B ± 0% 112B ± 0% -22.22% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
HeaderREMatcher-16 7.00 ± 0% 5.00 ± 0% -28.57% (p=0.000 n=10+10)
```
-rw-r--r-- | modules/caddyhttp/matchers.go | 5 | ||||
-rw-r--r-- | modules/caddyhttp/matchers_test.go | 26 |
2 files changed, 29 insertions, 2 deletions
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go index a4f4502..eaf43e9 100644 --- a/modules/caddyhttp/matchers.go +++ b/modules/caddyhttp/matchers.go @@ -24,6 +24,7 @@ import ( "path/filepath" "regexp" "sort" + "strconv" "strings" "github.com/caddyserver/caddy/v2" @@ -935,14 +936,14 @@ func (mre *MatchRegexp) Match(input string, repl *caddy.Replacer) bool { // save all capture groups, first by index for i, match := range matches { - key := fmt.Sprintf("%s.%d", mre.phPrefix, i) + key := mre.phPrefix + "." + strconv.Itoa(i) repl.Set(key, match) } // then by name for i, name := range mre.compiled.SubexpNames() { if i != 0 && name != "" { - key := fmt.Sprintf("%s.%s", mre.phPrefix, name) + key := mre.phPrefix + "." + name repl.Set(key, matches[i]) } } diff --git a/modules/caddyhttp/matchers_test.go b/modules/caddyhttp/matchers_test.go index 5163df1..950020f 100644 --- a/modules/caddyhttp/matchers_test.go +++ b/modules/caddyhttp/matchers_test.go @@ -692,6 +692,32 @@ func TestHeaderREMatcher(t *testing.T) { } } +func BenchmarkHeaderREMatcher(b *testing.B) { + + i := 0 + match := MatchHeaderRE{"Field": &MatchRegexp{Pattern: "^foo(.*)$", Name: "name"}} + input := http.Header{"Field": []string{"foobar"}} + var host string + err := match.Provision(caddy.Context{}) + if err != nil { + b.Errorf("Test %d %v: Provisioning: %v", i, match, err) + } + err = match.Validate() + if err != nil { + b.Errorf("Test %d %v: Validating: %v", i, match, err) + } + + // set up the fake request and its Replacer + req := &http.Request{Header: input, URL: new(url.URL), Host: host} + repl := caddy.NewReplacer() + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl) + req = req.WithContext(ctx) + addHTTPVarsToReplacer(repl, req, httptest.NewRecorder()) + for run := 0; run < b.N; run++ { + match.Match(req) + } +} + func TestVarREMatcher(t *testing.T) { for i, tc := range []struct { desc string |