Subtests & Sub-benchmark in Go1.7
Table-driven benchmarking
In Go1.7, `testing` package will supports subtests and sub-benchmark. With this feature, you can define tests/benchmarks in test/benchmark function. It’s easy to create hierarchical tests or table-driven sub-benchmark. It also provides a way to share common setup and tear-down code.
This feature may have less benefits on test because normally table-driven test is enough. It will improve your benchmark codes a lot.
Let me show some sample codes. For example, when you want to take benchmark of function `Foo` with different configuration, before Go1.7, you need to prepare functions for each configuration.
// you need to prepare functions for each bench mark setting
func BenchmarkFoo1(b *testing.B) { benchFoo(b, 1) }
func BenchmarkFoo10(b *testing.B) { benchFoo(b, 10) }
func BenchmarkFoo100(b *testing.B) { benchFoo(b, 100) }
// helper function to run Foo with different config
func benchFoo(b *testing.B, config int) {
for i := 0; i < b.N; i++ {
Foo(base)
}
If you use Sub-benchmark feature in Go1.7, you can write this benchmark like the following.
func BenchmarkFoo(b *testing.B) {
cases := []struct {
Config int
}{
{Config: 1},
{Config: 10},
{Config: 100},
} for _, bc := range cases {
b.Run(fmt.Sprintf(“%d”, bc.Config), func(b *testing.B) { benchFoo(b, bc.Base) })
}
}You can use table-driven approach! It’s simple and easy to read (Benchmark name will be Top level function name + first argument of `Run` method. e.g., `BenchmarkFoo/1`, `BenchmarkFoo/2`… )
If you check standard library changes in Go1.7, you can see it benefits from sub-benchmarks a lot. The followings are some of examples,