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)
```
This commit is contained in:
Calvin Xiao 2021-05-03 00:35:28 +08:00 committed by GitHub
parent 637fd8f67b
commit 53ececda21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View file

@ -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])
}
}

View file

@ -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