]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: remove an allocation in ServeMux
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 5 Jun 2018 21:06:17 +0000 (21:06 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 6 Jun 2018 01:47:31 +0000 (01:47 +0000)
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: Emmanuel Odeke <emm.odeke@gmail.com>
src/net/http/serve_test.go
src/net/http/server.go

index c14d87dcf9abf9bfb45722bd93fd4ba114bcf8db..10651fff7c40f4c7672114f261ed3732a9ac2a72 100644 (file)
@@ -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)
+                               }
                        }
                }
        }
index 0ac7c96de7b0be91ebbaf635c1aae645c7d96d42..407546d6c9e1186f3df298baa3895914ef85c7c4 100644 (file)
@@ -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
 }