mirror of
https://github.com/golang/go
synced 2024-10-03 05:21:22 -06: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
|
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.
|
// ReadRequest reads and parses a request from b.
|
||||||
func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
||||||
|
|
||||||
tp := textproto.NewReader(b)
|
tp := newTextprotoReader(b)
|
||||||
req = new(Request)
|
req = new(Request)
|
||||||
|
|
||||||
// First line: GET /index.html HTTP/1.0
|
// First line: GET /index.html HTTP/1.0
|
||||||
@ -490,6 +511,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
putTextprotoReader(tp)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
err = io.ErrUnexpectedEOF
|
err = io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user