1
0
mirror of https://github.com/golang/go synced 2024-10-03 00:11: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:
Brad Fitzpatrick 2013-03-28 14:51:21 -07:00
parent f1b7c140ff
commit 1b0d04b89f

View File

@ -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
}