Commit fdbbb066 authored by Nigel Tao's avatar Nigel Tao

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
parent 5b1d47d1
...@@ -76,7 +76,15 @@ func (d *decoder) readMSB() (uint16, os.Error) { ...@@ -76,7 +76,15 @@ func (d *decoder) readMSB() (uint16, os.Error) {
// decode decompresses bytes from r and writes them to pw. // decode decompresses bytes from r and writes them to pw.
// read specifies how to decode bytes into codes. // read specifies how to decode bytes into codes.
// litWidth is the width in bits of literal 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 ( const (
maxWidth = 12 maxWidth = 12
invalidCode = 0xffff invalidCode = 0xffff
...@@ -197,12 +205,6 @@ func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser { ...@@ -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)) pw.CloseWithError(fmt.Errorf("lzw: litWidth %d out of range", litWidth))
return pr return pr
} }
go func() { go decode(r, read, litWidth, pw)
br, ok := r.(io.ByteReader)
if !ok {
br = bufio.NewReader(r)
}
pw.CloseWithError(decode(pw, br, read, uint(litWidth)))
}()
return pr return pr
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment