Closed
Description
What version of Go are you using (go version
)?
go version go1.11.2 linux/amd64
Does this issue reproduce with the latest release?
Yes
What did you do?
When using net/http's server, and profiling with pprof shows that the "Header.clone" function takes up a lot of allocations (4% of my application's allocations, actually).
Solution
Could we improve the function to perform fewer allocations!
(NB. Note that Reader.ReadMIMEHeader in net/textproto already uses exactly this same trick, of using three-argument slicing to build the http.Header using a single []string
. So the pattern already exists in the codebase.)
--- /tmp/header-v1.go 2019-01-24 11:18:01.182761218 +0000
+++ /tmp/header-v2.go 2019-01-24 11:17:42.367569268 +0000
@@ -1,9 +1,17 @@
func (h Header) clone() Header {
h2 := make(Header, len(h))
+ sliceLen := 0
+ for _, vv := range h {
+ sliceLen += len(vv)
+ }
+ slice := make([]string, sliceLen)
+ sliceLen = 0
for k, vv := range h {
- vv2 := make([]string, len(vv))
+ vv2 := slice[sliceLen:sliceLen+len(vv):sliceLen+len(vv)]
+ sliceLen += len(vv)
copy(vv2, vv)
h2[k] = vv2
}
return h2
}