Commit 2ce295e9 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: remove an allocation in ServeMux

Also, add a benchmark variant ("SkipServe") that only benchmarks the
ServeMux handler selection path.

name                  old time/op    new time/op    delta
ServeMux_SkipServe-4    74.2µs ± 2%    60.6µs ± 1%   -18.31%   (p=0.000 n=10+9)

name                  old alloc/op   new alloc/op   delta
ServeMux_SkipServe-4    2.62kB ± 0%   0.00kB ±NaN%  -100.00%  (p=0.000 n=10+10)

name                  old allocs/op  new allocs/op  delta
ServeMux_SkipServe-4       180 ± 0%        0 ±NaN%  -100.00%  (p=0.000 n=10+10)

Updates #25383

Change-Id: Icfbb3b977e309093d032e922d1b4f254df6f5955
Reviewed-on: https://go-review.googlesource.com/116378
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
parent ebb8a1f8
......@@ -608,8 +608,9 @@ func TestShouldRedirectConcurrency(t *testing.T) {
mux.HandleFunc("/", func(w ResponseWriter, r *Request) {})
}
func BenchmarkServeMux(b *testing.B) {
func BenchmarkServeMux(b *testing.B) { benchmarkServeMux(b, true) }
func BenchmarkServeMux_SkipServe(b *testing.B) { benchmarkServeMux(b, false) }
func benchmarkServeMux(b *testing.B, runHandler bool) {
type test struct {
path string
code int
......@@ -641,9 +642,11 @@ func BenchmarkServeMux(b *testing.B) {
for _, tt := range tests {
*rw = httptest.ResponseRecorder{}
h, pattern := mux.Handler(tt.req)
h.ServeHTTP(rw, tt.req)
if pattern != tt.path || rw.Code != tt.code {
b.Fatalf("got %d, %q, want %d, %q", rw.Code, pattern, tt.code, tt.path)
if runHandler {
h.ServeHTTP(rw, tt.req)
if pattern != tt.path || rw.Code != tt.code {
b.Fatalf("got %d, %q, want %d, %q", rw.Code, pattern, tt.code, tt.path)
}
}
}
}
......
......@@ -2182,7 +2182,12 @@ func cleanPath(p string) string {
// path.Clean removes trailing slash except for root;
// put the trailing slash back if necessary.
if p[len(p)-1] == '/' && np != "/" {
np += "/"
// Fast path for common case of p being the string we want:
if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
np = p
} else {
np += "/"
}
}
return np
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment