1
0
mirror of https://github.com/golang/go synced 2024-11-25 05:57:57 -07:00

compress/lzw: don't use a closure in NewReader, which avoids having

to move some variables from the stack to the heap.

Sorted benchmark runs on my 2007-era Mac Mini (GOARCH=amd64, GOOS=linux):

Before:
lzw.BenchmarkDecoder        2000        878176 ns/op
lzw.BenchmarkDecoder        2000        878415 ns/op
lzw.BenchmarkDecoder        2000        880352 ns/op
lzw.BenchmarkDecoder        2000        898445 ns/op
lzw.BenchmarkDecoder        2000        901728 ns/op

After:
lzw.BenchmarkDecoder        2000        859065 ns/op
lzw.BenchmarkDecoder        2000        859402 ns/op
lzw.BenchmarkDecoder        2000        860035 ns/op
lzw.BenchmarkDecoder        2000        860555 ns/op
lzw.BenchmarkDecoder        2000        861109 ns/op

The ratio of before/after median times is 1.024.

The runtime.MemStats.Mallocs delta per loop drops from 109 to 104.

R=r, r2, dfc
CC=golang-dev
https://golang.org/cl/4253043
This commit is contained in:
Nigel Tao 2011-02-26 16:42:49 +11:00
parent 5b1d47d105
commit fdbbb066ed

View File

@ -76,7 +76,15 @@ func (d *decoder) readMSB() (uint16, os.Error) {
// decode decompresses bytes from r and writes them to pw.
// read specifies how to decode bytes into codes.
// litWidth is the width in bits of literal codes.
func decode(pw *io.PipeWriter, r io.ByteReader, read func(*decoder) (uint16, os.Error), litWidth uint) os.Error {
func decode(r io.Reader, read func(*decoder) (uint16, os.Error), litWidth int, pw *io.PipeWriter) {
br, ok := r.(io.ByteReader)
if !ok {
br = bufio.NewReader(r)
}
pw.CloseWithError(decode1(pw, br, read, uint(litWidth)))
}
func decode1(pw *io.PipeWriter, r io.ByteReader, read func(*decoder) (uint16, os.Error), litWidth uint) os.Error {
const (
maxWidth = 12
invalidCode = 0xffff
@ -197,12 +205,6 @@ func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
pw.CloseWithError(fmt.Errorf("lzw: litWidth %d out of range", litWidth))
return pr
}
go func() {
br, ok := r.(io.ByteReader)
if !ok {
br = bufio.NewReader(r)
}
pw.CloseWithError(decode(pw, br, read, uint(litWidth)))
}()
go decode(r, read, litWidth, pw)
return pr
}