mirror of
https://github.com/golang/go
synced 2024-11-20 07:24:40 -07:00
compress/lzw: fix the stupidity of allocating and zeroing a new buffer
on each loop iteration, yielding a 20x performance improvement. R=rsc, r2 CC=golang-dev https://golang.org/cl/4240044
This commit is contained in:
parent
54f0040723
commit
5b1d47d105
@ -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.
|
// The c == hi case is a special case.
|
||||||
suffix [1 << maxWidth]uint8
|
suffix [1 << maxWidth]uint8
|
||||||
prefix [1 << maxWidth]uint16
|
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.
|
// 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:
|
case code == eof:
|
||||||
return w.Flush()
|
return w.Flush()
|
||||||
case code <= hi:
|
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
|
c, i := code, len(buf)-1
|
||||||
if code == hi {
|
if code == hi {
|
||||||
// code == hi is a special case which expands to the last expansion
|
// code == hi is a special case which expands to the last expansion
|
||||||
|
@ -7,6 +7,7 @@ package lzw
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user