mirror of
https://github.com/golang/go
synced 2024-11-27 04:31:21 -07:00
compress/flate: simplify using subtests and sub-benchmarks
This causes the large files to be loaded only once per benchmark. This CL also serves as an example use case of sub(tests|-benchmarks). This CL ensures that names are identical to the original except for an added slashes. Things could be simplified further if this restriction were dropped. Change-Id: I45e303e158e3152e33d0d751adfef784713bf997 Reviewed-on: https://go-review.googlesource.com/23420 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Marcel van Lohuizen <mpvl@golang.org> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
89283781c6
commit
d2aa5f95cc
@ -22,82 +22,77 @@ func TestNlitOutOfRange(t *testing.T) {
|
||||
"\x75\xc4\xf8\x0f\x12\x11\xb9\xb4\x4b\x09\xa0\xbe\x8b\x91\x4c")))
|
||||
}
|
||||
|
||||
const (
|
||||
digits = iota
|
||||
twain
|
||||
)
|
||||
|
||||
var testfiles = []string{
|
||||
var suites = []struct{ name, file string }{
|
||||
// Digits is the digits of the irrational number e. Its decimal representation
|
||||
// does not repeat, but there are only 10 possible digits, so it should be
|
||||
// reasonably compressible.
|
||||
digits: "../testdata/e.txt",
|
||||
{"Digits", "../testdata/e.txt"},
|
||||
// Twain is Mark Twain's classic English novel.
|
||||
twain: "../testdata/Mark.Twain-Tom.Sawyer.txt",
|
||||
{"Twain", "../testdata/Mark.Twain-Tom.Sawyer.txt"},
|
||||
}
|
||||
|
||||
func benchmarkDecode(b *testing.B, testfile, level, n int) {
|
||||
b.ReportAllocs()
|
||||
b.StopTimer()
|
||||
b.SetBytes(int64(n))
|
||||
buf0, err := ioutil.ReadFile(testfiles[testfile])
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if len(buf0) == 0 {
|
||||
b.Fatalf("test file %q has no data", testfiles[testfile])
|
||||
}
|
||||
compressed := new(bytes.Buffer)
|
||||
w, err := NewWriter(compressed, level)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
for i := 0; i < n; i += len(buf0) {
|
||||
if len(buf0) > n-i {
|
||||
buf0 = buf0[:n-i]
|
||||
func BenchmarkDecode(b *testing.B) {
|
||||
doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
|
||||
b.ReportAllocs()
|
||||
b.StopTimer()
|
||||
b.SetBytes(int64(n))
|
||||
|
||||
compressed := new(bytes.Buffer)
|
||||
w, err := NewWriter(compressed, level)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
io.Copy(w, bytes.NewReader(buf0))
|
||||
}
|
||||
w.Close()
|
||||
buf1 := compressed.Bytes()
|
||||
buf0, compressed, w = nil, nil, nil
|
||||
runtime.GC()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1)))
|
||||
}
|
||||
for i := 0; i < n; i += len(buf0) {
|
||||
if len(buf0) > n-i {
|
||||
buf0 = buf0[:n-i]
|
||||
}
|
||||
io.Copy(w, bytes.NewReader(buf0))
|
||||
}
|
||||
w.Close()
|
||||
buf1 := compressed.Bytes()
|
||||
buf0, compressed, w = nil, nil, nil
|
||||
runtime.GC()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// These short names are so that gofmt doesn't break the BenchmarkXxx function
|
||||
// bodies below over multiple lines.
|
||||
const (
|
||||
speed = BestSpeed
|
||||
default_ = DefaultCompression
|
||||
compress = BestCompression
|
||||
huffman = HuffmanOnly
|
||||
)
|
||||
var levelTests = []struct {
|
||||
name string
|
||||
level int
|
||||
}{
|
||||
{"Huffman", HuffmanOnly},
|
||||
{"Speed", BestSpeed},
|
||||
{"Default", DefaultCompression},
|
||||
{"Compression", BestCompression},
|
||||
}
|
||||
|
||||
func BenchmarkDecodeDigitsHuffman1e4(b *testing.B) { benchmarkDecode(b, digits, huffman, 1e4) }
|
||||
func BenchmarkDecodeDigitsHuffman1e5(b *testing.B) { benchmarkDecode(b, digits, huffman, 1e5) }
|
||||
func BenchmarkDecodeDigitsHuffman1e6(b *testing.B) { benchmarkDecode(b, digits, huffman, 1e6) }
|
||||
func BenchmarkDecodeDigitsSpeed1e4(b *testing.B) { benchmarkDecode(b, digits, speed, 1e4) }
|
||||
func BenchmarkDecodeDigitsSpeed1e5(b *testing.B) { benchmarkDecode(b, digits, speed, 1e5) }
|
||||
func BenchmarkDecodeDigitsSpeed1e6(b *testing.B) { benchmarkDecode(b, digits, speed, 1e6) }
|
||||
func BenchmarkDecodeDigitsDefault1e4(b *testing.B) { benchmarkDecode(b, digits, default_, 1e4) }
|
||||
func BenchmarkDecodeDigitsDefault1e5(b *testing.B) { benchmarkDecode(b, digits, default_, 1e5) }
|
||||
func BenchmarkDecodeDigitsDefault1e6(b *testing.B) { benchmarkDecode(b, digits, default_, 1e6) }
|
||||
func BenchmarkDecodeDigitsCompress1e4(b *testing.B) { benchmarkDecode(b, digits, compress, 1e4) }
|
||||
func BenchmarkDecodeDigitsCompress1e5(b *testing.B) { benchmarkDecode(b, digits, compress, 1e5) }
|
||||
func BenchmarkDecodeDigitsCompress1e6(b *testing.B) { benchmarkDecode(b, digits, compress, 1e6) }
|
||||
func BenchmarkDecodeTwainHuffman1e4(b *testing.B) { benchmarkDecode(b, twain, huffman, 1e4) }
|
||||
func BenchmarkDecodeTwainHuffman1e5(b *testing.B) { benchmarkDecode(b, twain, huffman, 1e5) }
|
||||
func BenchmarkDecodeTwainHuffman1e6(b *testing.B) { benchmarkDecode(b, twain, huffman, 1e6) }
|
||||
func BenchmarkDecodeTwainSpeed1e4(b *testing.B) { benchmarkDecode(b, twain, speed, 1e4) }
|
||||
func BenchmarkDecodeTwainSpeed1e5(b *testing.B) { benchmarkDecode(b, twain, speed, 1e5) }
|
||||
func BenchmarkDecodeTwainSpeed1e6(b *testing.B) { benchmarkDecode(b, twain, speed, 1e6) }
|
||||
func BenchmarkDecodeTwainDefault1e4(b *testing.B) { benchmarkDecode(b, twain, default_, 1e4) }
|
||||
func BenchmarkDecodeTwainDefault1e5(b *testing.B) { benchmarkDecode(b, twain, default_, 1e5) }
|
||||
func BenchmarkDecodeTwainDefault1e6(b *testing.B) { benchmarkDecode(b, twain, default_, 1e6) }
|
||||
func BenchmarkDecodeTwainCompress1e4(b *testing.B) { benchmarkDecode(b, twain, compress, 1e4) }
|
||||
func BenchmarkDecodeTwainCompress1e5(b *testing.B) { benchmarkDecode(b, twain, compress, 1e5) }
|
||||
func BenchmarkDecodeTwainCompress1e6(b *testing.B) { benchmarkDecode(b, twain, compress, 1e6) }
|
||||
var sizes = []struct {
|
||||
name string
|
||||
n int
|
||||
}{
|
||||
{"1e4", 1e4},
|
||||
{"1e5", 1e5},
|
||||
{"1e6", 1e6},
|
||||
}
|
||||
|
||||
func doBench(b *testing.B, f func(b *testing.B, buf []byte, level, n int)) {
|
||||
for _, suite := range suites {
|
||||
buf, err := ioutil.ReadFile(suite.file)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if len(buf) == 0 {
|
||||
b.Fatalf("test file %q has no data", suite.file)
|
||||
}
|
||||
for _, l := range levelTests {
|
||||
for _, s := range sizes {
|
||||
b.Run(suite.name+"/"+l.name+"/"+s.name, func(b *testing.B) {
|
||||
f(b, buf, l.level, s.n)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,61 +14,32 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func benchmarkEncoder(b *testing.B, testfile, level, n int) {
|
||||
b.StopTimer()
|
||||
b.SetBytes(int64(n))
|
||||
buf0, err := ioutil.ReadFile(testfiles[testfile])
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if len(buf0) == 0 {
|
||||
b.Fatalf("test file %q has no data", testfiles[testfile])
|
||||
}
|
||||
buf1 := make([]byte, n)
|
||||
for i := 0; i < n; i += len(buf0) {
|
||||
if len(buf0) > n-i {
|
||||
buf0 = buf0[:n-i]
|
||||
}
|
||||
copy(buf1[i:], buf0)
|
||||
}
|
||||
buf0 = nil
|
||||
w, err := NewWriter(ioutil.Discard, level)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
runtime.GC()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
w.Reset(ioutil.Discard)
|
||||
w.Write(buf1)
|
||||
w.Close()
|
||||
}
|
||||
}
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
|
||||
b.StopTimer()
|
||||
b.SetBytes(int64(n))
|
||||
|
||||
func BenchmarkEncodeDigitsHuffman1e4(b *testing.B) { benchmarkEncoder(b, digits, huffman, 1e4) }
|
||||
func BenchmarkEncodeDigitsHuffman1e5(b *testing.B) { benchmarkEncoder(b, digits, huffman, 1e5) }
|
||||
func BenchmarkEncodeDigitsHuffman1e6(b *testing.B) { benchmarkEncoder(b, digits, huffman, 1e6) }
|
||||
func BenchmarkEncodeDigitsSpeed1e4(b *testing.B) { benchmarkEncoder(b, digits, speed, 1e4) }
|
||||
func BenchmarkEncodeDigitsSpeed1e5(b *testing.B) { benchmarkEncoder(b, digits, speed, 1e5) }
|
||||
func BenchmarkEncodeDigitsSpeed1e6(b *testing.B) { benchmarkEncoder(b, digits, speed, 1e6) }
|
||||
func BenchmarkEncodeDigitsDefault1e4(b *testing.B) { benchmarkEncoder(b, digits, default_, 1e4) }
|
||||
func BenchmarkEncodeDigitsDefault1e5(b *testing.B) { benchmarkEncoder(b, digits, default_, 1e5) }
|
||||
func BenchmarkEncodeDigitsDefault1e6(b *testing.B) { benchmarkEncoder(b, digits, default_, 1e6) }
|
||||
func BenchmarkEncodeDigitsCompress1e4(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e4) }
|
||||
func BenchmarkEncodeDigitsCompress1e5(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e5) }
|
||||
func BenchmarkEncodeDigitsCompress1e6(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e6) }
|
||||
func BenchmarkEncodeTwainHuffman1e4(b *testing.B) { benchmarkEncoder(b, twain, huffman, 1e4) }
|
||||
func BenchmarkEncodeTwainHuffman1e5(b *testing.B) { benchmarkEncoder(b, twain, huffman, 1e5) }
|
||||
func BenchmarkEncodeTwainHuffman1e6(b *testing.B) { benchmarkEncoder(b, twain, huffman, 1e6) }
|
||||
func BenchmarkEncodeTwainSpeed1e4(b *testing.B) { benchmarkEncoder(b, twain, speed, 1e4) }
|
||||
func BenchmarkEncodeTwainSpeed1e5(b *testing.B) { benchmarkEncoder(b, twain, speed, 1e5) }
|
||||
func BenchmarkEncodeTwainSpeed1e6(b *testing.B) { benchmarkEncoder(b, twain, speed, 1e6) }
|
||||
func BenchmarkEncodeTwainDefault1e4(b *testing.B) { benchmarkEncoder(b, twain, default_, 1e4) }
|
||||
func BenchmarkEncodeTwainDefault1e5(b *testing.B) { benchmarkEncoder(b, twain, default_, 1e5) }
|
||||
func BenchmarkEncodeTwainDefault1e6(b *testing.B) { benchmarkEncoder(b, twain, default_, 1e6) }
|
||||
func BenchmarkEncodeTwainCompress1e4(b *testing.B) { benchmarkEncoder(b, twain, compress, 1e4) }
|
||||
func BenchmarkEncodeTwainCompress1e5(b *testing.B) { benchmarkEncoder(b, twain, compress, 1e5) }
|
||||
func BenchmarkEncodeTwainCompress1e6(b *testing.B) { benchmarkEncoder(b, twain, compress, 1e6) }
|
||||
buf1 := make([]byte, n)
|
||||
for i := 0; i < n; i += len(buf0) {
|
||||
if len(buf0) > n-i {
|
||||
buf0 = buf0[:n-i]
|
||||
}
|
||||
copy(buf1[i:], buf0)
|
||||
}
|
||||
buf0 = nil
|
||||
w, err := NewWriter(ioutil.Discard, level)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
runtime.GC()
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
w.Reset(ioutil.Discard)
|
||||
w.Write(buf1)
|
||||
w.Close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// errorWriter is a writer that fails after N writes.
|
||||
type errorWriter struct {
|
||||
@ -141,17 +112,12 @@ func TestWriteError(t *testing.T) {
|
||||
|
||||
// Test if two runs produce identical results
|
||||
// even when writing different sizes to the Writer.
|
||||
func TestDeterministicL0(t *testing.T) { testDeterministic(0, t) }
|
||||
func TestDeterministicL1(t *testing.T) { testDeterministic(1, t) }
|
||||
func TestDeterministicL2(t *testing.T) { testDeterministic(2, t) }
|
||||
func TestDeterministicL3(t *testing.T) { testDeterministic(3, t) }
|
||||
func TestDeterministicL4(t *testing.T) { testDeterministic(4, t) }
|
||||
func TestDeterministicL5(t *testing.T) { testDeterministic(5, t) }
|
||||
func TestDeterministicL6(t *testing.T) { testDeterministic(6, t) }
|
||||
func TestDeterministicL7(t *testing.T) { testDeterministic(7, t) }
|
||||
func TestDeterministicL8(t *testing.T) { testDeterministic(8, t) }
|
||||
func TestDeterministicL9(t *testing.T) { testDeterministic(9, t) }
|
||||
func TestDeterministicLM2(t *testing.T) { testDeterministic(-2, t) }
|
||||
func TestDeterministic(t *testing.T) {
|
||||
for i := 0; i <= 9; i++ {
|
||||
t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) })
|
||||
}
|
||||
t.Run("LM2", func(t *testing.T) { testDeterministic(-2, t) })
|
||||
}
|
||||
|
||||
func testDeterministic(i int, t *testing.T) {
|
||||
// Test so much we cross a good number of block boundaries.
|
||||
|
Loading…
Reference in New Issue
Block a user