]> Cypherpunks repositories - gostls13.git/commitdiff
net/http/httputil: eliminate duplicate alloc/copy in ReverseProxy
authorBlake Mizerany <blake.mizerany@gmail.com>
Mon, 23 Jan 2017 19:03:03 +0000 (11:03 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 1 Feb 2017 21:43:05 +0000 (21:43 +0000)
This commit elimates the request allocation and shallow copy duplication
already done by req.WithContext.

name         old time/op    new time/op    delta
ServeHTTP-4     216µs ±36%     212µs ±15%     ~     (p=0.853 n=10+10)

name         old alloc/op   new alloc/op   delta
ServeHTTP-4     917kB ±36%    1137kB ± 0%     ~     (p=0.352 n=10+10)

name         old allocs/op  new allocs/op  delta
ServeHTTP-4      5.00 ± 0%      4.00 ± 0%  -20.00%  (p=0.000 n=10+10)

Change-Id: I514a59c30b037c7a65c355b06fd82c2d6ff17bb0
Reviewed-on: https://go-review.googlesource.com/35569
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/httputil/reverseproxy.go
src/net/http/httputil/reverseproxy_test.go

index 79c8fe27702fbbece3b81451c9aa23db5891ecfc..60b94d764955964eb5400399e1c7e13b5b8ef569 100644 (file)
@@ -149,12 +149,10 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
                }()
        }
 
-       outreq := new(http.Request)
-       *outreq = *req // includes shallow copies of maps, but okay
+       outreq := req.WithContext(ctx) // includes shallow copies of maps, but okay
        if req.ContentLength == 0 {
                outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
        }
-       outreq = outreq.WithContext(ctx)
 
        p.Director(outreq)
        outreq.Close = false
index 20c4e16bcb8b30387e1e452d9b3d6ce195638ece..9153508ef4b2f954c18e2aae6026dbda9d1baa87 100644 (file)
@@ -664,3 +664,30 @@ func TestReverseProxy_CopyBuffer(t *testing.T) {
                }
        }
 }
+
+type staticTransport struct {
+       res *http.Response
+}
+
+func (t *staticTransport) RoundTrip(r *http.Request) (*http.Response, error) {
+       return t.res, nil
+}
+
+func BenchmarkServeHTTP(b *testing.B) {
+       res := &http.Response{
+               StatusCode: 200,
+               Body:       ioutil.NopCloser(strings.NewReader("")),
+       }
+       proxy := &ReverseProxy{
+               Director:  func(*http.Request) {},
+               Transport: &staticTransport{res},
+       }
+
+       w := httptest.NewRecorder()
+       r := httptest.NewRequest("GET", "/", nil)
+
+       b.ReportAllocs()
+       for i := 0; i < b.N; i++ {
+               proxy.ServeHTTP(w, r)
+       }
+}