-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Closed
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.Performance
Milestone
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
}
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.Performance