diff --git a/filters/builtin/stripquery.go b/filters/builtin/stripquery.go index 5dd533d017..d490a8088d 100644 --- a/filters/builtin/stripquery.go +++ b/filters/builtin/stripquery.go @@ -51,7 +51,8 @@ func validHeaderFieldByte(b byte) bool { } // make sure we don't generate invalid headers -func sanitize(input string) string { +// temporary public function to benchmark it +func Sanitize(input string) string { toAscii := strconv.QuoteToASCII(input) var b bytes.Buffer for _, i := range toAscii { @@ -62,6 +63,18 @@ func sanitize(input string) string { return b.String() } +// temporary public function to benchmark it +func NewSanitize(input string) string { + toAscii := strconv.QuoteToASCII(input) + var s strings.Builder + for _, i := range toAscii { + if validHeaderFieldByte(byte(i)) { + s.WriteRune(i) + } + } + return s.String() +} + // Strips the query parameters and optionally preserves them in the X-Query-Param-xyz headers. func (f *stripQuery) Request(ctx filters.FilterContext) { r := ctx.Request() @@ -85,7 +98,7 @@ func (f *stripQuery) Request(ctx filters.FilterContext) { if r.Header == nil { r.Header = http.Header{} } - r.Header.Add(fmt.Sprintf("X-Query-Param-%s", sanitize(k)), v) + r.Header.Add(fmt.Sprintf("X-Query-Param-%s", Sanitize(k)), v) } } diff --git a/filters/builtin/stripquery_test.go b/filters/builtin/stripquery_test.go index 643623ae11..17079cc9a0 100644 --- a/filters/builtin/stripquery_test.go +++ b/filters/builtin/stripquery_test.go @@ -15,11 +15,13 @@ package builtin import ( - "github.com/zalando/skipper/filters/filtertest" + "fmt" "net/http" "net/url" "strings" "testing" + + "github.com/zalando/skipper/filters/filtertest" ) func TestCreateStripQueryFilter(t *testing.T) { @@ -91,3 +93,38 @@ func TestPreserveQuery(t *testing.T) { } } } + +func BenchmarkStripQuery(b *testing.B) { + var table = []struct { + url string + }{ + {url: "http://example.org/foo?bar=baz"}, + {url: "http://example.org/foo?query=cXVlcnkgewogIG5hbWUKfQo%253D&variables=&apiEndpoint=https%253A%252F%252Fwww.zalando.de%252Fapi%252Fgraphql%252Fpreview&frontendType=web&zalandoFeature=manual"}, + {url: "http://example.org/foo?馬鹿=123"}, + {url: "http://example.org/foo?a%20b=123"}, + } + + for i, v := range table { + url, _ := url.ParseRequestURI(v.url) + q := url.Query() + b.Run(fmt.Sprintf("[old sanitize] url %d", i+1), func(b *testing.B) { + for i := 0; i < b.N; i++ { + for k := range q { + Sanitize(k) + } + } + }) + } + + for i, v := range table { + url, _ := url.ParseRequestURI(v.url) + q := url.Query() + b.Run(fmt.Sprintf("[new sanitize] url %d", i + 1), func(b *testing.B) { + for i := 0; i < b.N; i++ { + for k := range q { + NewSanitize(k) + } + } + }) + } +} diff --git a/results.md b/results.md new file mode 100644 index 0000000000..028b100ecc --- /dev/null +++ b/results.md @@ -0,0 +1,14 @@ +`go test -benchmem -run=^$ -bench ^BenchmarkStripQuery$ -benchtime=10s github.com/zalando/skipper/filters/builtin` + +``` +BenchmarkStripQuery/[old_sanitize]_url_1-8 85732707 118.6 ns/op 80 B/op 4 allocs/op +BenchmarkStripQuery/[old_sanitize]_url_2-8 14885370 808.2 ns/op 472 B/op 15 allocs/op +BenchmarkStripQuery/[old_sanitize]_url_3-8 73297474 162.9 ns/op 120 B/op 4 allocs/op +BenchmarkStripQuery/[old_sanitize]_url_4-8 100000000 114.1 ns/op 80 B/op 4 allocs/op + + +BenchmarkStripQuery/[new_sanitize]_url_1-8 100000000 103.5 ns/op 24 B/op 3 allocs/op +BenchmarkStripQuery/[new_sanitize]_url_2-8 15854868 778.5 ns/op 192 B/op 14 allocs/op +BenchmarkStripQuery/[new_sanitize]_url_3-8 71689101 166.3 ns/op 64 B/op 4 allocs/op +BenchmarkStripQuery/[new_sanitize]_url_4-8 100000000 102.0 ns/op 24 B/op 3 allocs/op +``` \ No newline at end of file