mirror of https://github.com/golang/go.git
net/textproto: more efficient header parsing
A co creation with bradfitz
* add fast path for header lines which are not continuations
* pass hint to better size initial mime header map
lucky(~/go/src/pkg/net/http) % ~/go/misc/benchcmp {golden,new}.txt
benchmark old ns/op new ns/op delta
BenchmarkReadRequestChrome 10073 8348 -17.12%
BenchmarkReadRequestCurl 4368 4350 -0.41%
BenchmarkReadRequestApachebench 4412 4397 -0.34%
BenchmarkReadRequestSiege 6431 5924 -7.88%
BenchmarkReadRequestWrk 2820 3146 +11.56%
benchmark old MB/s new MB/s speedup
BenchmarkReadRequestChrome 60.66 73.18 1.21x
BenchmarkReadRequestCurl 17.85 17.93 1.00x
BenchmarkReadRequestApachebench 18.58 18.65 1.00x
BenchmarkReadRequestSiege 23.48 25.49 1.09x
BenchmarkReadRequestWrk 14.18 12.71 0.90x
benchmark old allocs new allocs delta
BenchmarkReadRequestChrome 32 26 -18.75%
BenchmarkReadRequestCurl 15 15 0.00%
BenchmarkReadRequestApachebench 16 15 -6.25%
BenchmarkReadRequestSiege 22 19 -13.64%
BenchmarkReadRequestWrk 11 11 0.00%
benchmark old bytes new bytes delta
BenchmarkReadRequestChrome 3148 2216 -29.61%
BenchmarkReadRequestCurl 905 1413 56.13%
BenchmarkReadRequestApachebench 956 1413 47.80%
BenchmarkReadRequestSiege 1397 1522 8.95%
BenchmarkReadRequestWrk 757 1369 80.85%
R=bradfitz
CC=golang-dev
https://golang.org/cl/7300098
This commit is contained in:
parent
44d38ae3c0
commit
2803744b86
|
|
@ -128,6 +128,17 @@ func (r *Reader) readContinuedLineSlice() ([]byte, error) {
|
|||
return line, nil
|
||||
}
|
||||
|
||||
// Optimistically assume that we have started to buffer the next line
|
||||
// and it starts with an ASCII letter (the next header key), so we can
|
||||
// avoid copying that buffered data around in memory and skipping over
|
||||
// non-existent whitespace.
|
||||
if r.R.Buffered() > 1 {
|
||||
peek, err := r.R.Peek(1)
|
||||
if err == nil && isASCIILetter(peek[0]) {
|
||||
return trim(line), nil
|
||||
}
|
||||
}
|
||||
|
||||
// ReadByte or the next readLineSlice will flush the read buffer;
|
||||
// copy the slice into buf.
|
||||
r.buf = append(r.buf[:0], trim(line)...)
|
||||
|
|
@ -445,7 +456,7 @@ func (r *Reader) ReadDotLines() ([]string, error) {
|
|||
// }
|
||||
//
|
||||
func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
|
||||
m := make(MIMEHeader)
|
||||
m := make(MIMEHeader, 4)
|
||||
for {
|
||||
kv, err := r.readContinuedLineSlice()
|
||||
if len(kv) == 0 {
|
||||
|
|
|
|||
|
|
@ -147,3 +147,8 @@ func TrimBytes(b []byte) []byte {
|
|||
func isASCIISpace(b byte) bool {
|
||||
return b == ' ' || b == '\t' || b == '\n' || b == '\r'
|
||||
}
|
||||
|
||||
func isASCIILetter(b byte) bool {
|
||||
b |= 0x20 // make lower case
|
||||
return 'a' <= b && b <= 'z'
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue