mirror of
https://github.com/golang/go
synced 2024-11-20 01:44:42 -07:00
net/http: reuse textproto.Readers; remove 2 more allocations
Saves both the textproto.Reader allocation, and its internal scratch buffer growing. benchmark old ns/op new ns/op delta BenchmarkServerFakeConnWithKeepAliveLite 10324 10149 -1.70% benchmark old allocs new allocs delta BenchmarkServerFakeConnWithKeepAliveLite 19 17 -10.53% benchmark old bytes new bytes delta BenchmarkServerFakeConnWithKeepAliveLite 1559 1492 -4.30% R=golang-dev, r, gri CC=golang-dev https://golang.org/cl/8094046
This commit is contained in:
parent
f1b7c140ff
commit
1b0d04b89f
@ -478,10 +478,31 @@ func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
|
||||
return line[:s1], line[s1+1 : s2], line[s2+1:], true
|
||||
}
|
||||
|
||||
// TODO(bradfitz): use a sync.Cache when available
|
||||
var textprotoReaderCache = make(chan *textproto.Reader, 4)
|
||||
|
||||
func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
|
||||
select {
|
||||
case r := <-textprotoReaderCache:
|
||||
r.R = br
|
||||
return r
|
||||
default:
|
||||
return textproto.NewReader(br)
|
||||
}
|
||||
}
|
||||
|
||||
func putTextprotoReader(r *textproto.Reader) {
|
||||
r.R = nil
|
||||
select {
|
||||
case textprotoReaderCache <- r:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// ReadRequest reads and parses a request from b.
|
||||
func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
||||
|
||||
tp := textproto.NewReader(b)
|
||||
tp := newTextprotoReader(b)
|
||||
req = new(Request)
|
||||
|
||||
// First line: GET /index.html HTTP/1.0
|
||||
@ -490,6 +511,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
putTextprotoReader(tp)
|
||||
if err == io.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user