]> Cypherpunks repositories - gostls13.git/commitdiff
compress/flate: simplify using subtests and sub-benchmarks
authorMarcel van Lohuizen <mpvl@golang.org>
Wed, 25 May 2016 09:19:17 +0000 (11:19 +0200)
committerMarcel van Lohuizen <mpvl@golang.org>
Wed, 25 May 2016 17:44:22 +0000 (17:44 +0000)
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>

src/compress/flate/reader_test.go
src/compress/flate/writer_test.go

index b336278c07d0158efea45ea828f86b01c93b9f48..b0a16ce18b98d637063eb3d9ff843466999f9cf9 100644 (file)
@@ -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)
+                               })
+                       }
+               }
+       }
+}
index 7967cd739c5862d019e5d080e3523efc4a5747c2..21cd0b22eef5fe6e6185635f74de712c82b59fd9 100644 (file)
@@ -14,62 +14,33 @@ 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]
+func BenchmarkEncode(b *testing.B) {
+       doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
+               b.StopTimer()
+               b.SetBytes(int64(n))
+
+               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)
                }
-               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()
-       }
+               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 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) }
-
 // errorWriter is a writer that fails after N writes.
 type errorWriter struct {
        N int
@@ -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.