diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2011-05-25 10:15:26 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2011-05-25 10:15:26 -0700 |
| commit | b0f39cc27cb3bcd0c9a53b158d8ea04d6f5c2e28 (patch) | |
| tree | 682b003c35555606404aeea124fe0a1d34f57061 /src/pkg/http/server.go | |
| parent | e94eb38975ecdb3d4ed0a200671b6470c0b791a3 (diff) | |
| download | go-b0f39cc27cb3bcd0c9a53b158d8ea04d6f5c2e28.tar.xz | |
io, net, http: sendfile support
Speeds up static fileserver, avoiding kernel/userspace copies.
Numbers: downloading 14 MB AppEngine Go SDK with ab (Apache Bench)
with 5 threads:
Before/after numbers:
CPU:
user 0m3.910s
sys 0m23.650s
->
user 0m0.720s
sys 0m4.890s
Time taken for tests: 8.906 seconds
->
Time taken for tests: 8.545 seconds
Percentage of the requests served within a certain time (ms)
50% 44
66% 45
75% 46
80% 46
90% 48
95% 51
98% 59
99% 71
100 74 (longest request)
->
50% 42
66% 43
75% 43
80% 44
90% 46
95% 57
98% 62
99% 63
100% 64 (longest request)
R=iant, gary.burd, rsc, bradfitz
CC=golang-dev
https://golang.org/cl/4543071
Diffstat (limited to 'src/pkg/http/server.go')
| -rw-r--r-- | src/pkg/http/server.go | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/pkg/http/server.go b/src/pkg/http/server.go index eb5a3a365e..ffeac034ef 100644 --- a/src/pkg/http/server.go +++ b/src/pkg/http/server.go @@ -119,6 +119,27 @@ type response struct { closeAfterReply bool } +type writerOnly struct { + io.Writer +} + +func (r *response) ReadFrom(src io.Reader) (n int64, err os.Error) { + // Flush before checking r.chunking, as Flush will call + // WriteHeader if it hasn't been called yet, and WriteHeader + // is what sets r.chunking. + r.Flush() + if !r.chunking { + if rf, ok := r.conn.rwc.(io.ReaderFrom); ok { + n, err = rf.ReadFrom(src) + r.written += n + return + } + } + // Fall back to default io.Copy implementation. + // Use wrapper to hide r.ReadFrom from io.Copy. + return io.Copy(writerOnly{r}, src) +} + // Create new connection from rwc. func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) { c = new(conn) |
