]> Cypherpunks repositories - gostls13.git/commitdiff
compress/lzw: fix the stupidity of allocating and zeroing a new buffer
authorNigel Tao <nigeltao@golang.org>
Fri, 25 Feb 2011 22:25:29 +0000 (09:25 +1100)
committerNigel Tao <nigeltao@golang.org>
Fri, 25 Feb 2011 22:25:29 +0000 (09:25 +1100)
on each loop iteration, yielding a 20x performance improvement.

R=rsc, r2
CC=golang-dev
https://golang.org/cl/4240044

src/pkg/compress/lzw/reader.go
src/pkg/compress/lzw/reader_test.go
src/pkg/compress/lzw/writer_test.go

index 505b24bb5dc6cfc4390d470ef362b4692a13ccd6..9838acd4ea56bc98e44689177e629b990e081f3f 100644 (file)
@@ -99,6 +99,9 @@ func decode(pw *io.PipeWriter, r io.ByteReader, read func(*decoder) (uint16, os.
                // The c == hi case is a special case.
                suffix [1 << maxWidth]uint8
                prefix [1 << maxWidth]uint16
+               // buf is a scratch buffer for reconstituting the bytes that a code expands to.
+               // Code suffixes are written right-to-left from the end of the buffer.
+               buf [1 << maxWidth]byte
        )
 
        // Loop over the code stream, converting codes into decompressed bytes.
@@ -131,9 +134,6 @@ func decode(pw *io.PipeWriter, r io.ByteReader, read func(*decoder) (uint16, os.
                case code == eof:
                        return w.Flush()
                case code <= hi:
-                       // buf is a scratch buffer for reconstituting the bytes that a code expands to.
-                       // Code suffixes are written right-to-left from the end of the buffer.
-                       var buf [1 << maxWidth]byte
                        c, i := code, len(buf)-1
                        if code == hi {
                                // code == hi is a special case which expands to the last expansion
index cfc15065bb67c25227abdf25424d71684c4affd8..7795a4c14896486f07129ebea00addf3a9c0a27a 100644 (file)
@@ -7,6 +7,7 @@ package lzw
 import (
        "bytes"
        "io"
+       "io/ioutil"
        "os"
        "strconv"
        "strings"
@@ -109,3 +110,23 @@ func TestReader(t *testing.T) {
                }
        }
 }
+
+type devNull struct{}
+
+func (devNull) Write(p []byte) (int, os.Error) {
+       return len(p), nil
+}
+
+func BenchmarkDecoder(b *testing.B) {
+       b.StopTimer()
+       buf0, _ := ioutil.ReadFile("../testdata/e.txt")
+       compressed := bytes.NewBuffer(nil)
+       w := NewWriter(compressed, LSB, 8)
+       io.Copy(w, bytes.NewBuffer(buf0))
+       w.Close()
+       buf1 := compressed.Bytes()
+       b.StartTimer()
+       for i := 0; i < b.N; i++ {
+               io.Copy(devNull{}, NewReader(bytes.NewBuffer(buf1), LSB, 8))
+       }
+}
index 2199522f8e6101f5c31b830cb0cce7328c901c3f..715b974aa1ec20ab11fcb65ef1e95a51e938d2ab 100644 (file)
@@ -98,3 +98,14 @@ func TestWriter(t *testing.T) {
                }
        }
 }
+
+func BenchmarkEncoder(b *testing.B) {
+       b.StopTimer()
+       buf, _ := ioutil.ReadFile("../testdata/e.txt")
+       b.StartTimer()
+       for i := 0; i < b.N; i++ {
+               w := NewWriter(devNull{}, LSB, 8)
+               w.Write(buf)
+               w.Close()
+       }
+}