]> Cypherpunks repositories - gostls13.git/commitdiff
compress/lzw: don't use a closure in NewReader, which avoids having
authorNigel Tao <nigeltao@golang.org>
Sat, 26 Feb 2011 05:42:49 +0000 (16:42 +1100)
committerNigel Tao <nigeltao@golang.org>
Sat, 26 Feb 2011 05:42:49 +0000 (16:42 +1100)
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

src/pkg/compress/lzw/reader.go

index 9838acd4ea56bc98e44689177e629b990e081f3f..8a540cbe6a11c686cc036cfd05bf759ae1349d98 100644 (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
 }