Subtests & Sub-benchmarks in Go1.7

Table-driven benchmarking

deeeet
2 min readAug 9, 2016

In Go1.7, `testing` package will supports subtests and sub-benchmarks. With this feature, you can define tests/benchmarks in a test/benchmark function. It’s easy to create hierarchical tests or table-driven sub-benchmarks. It also provides a way to share common setup and tear-down code.

This feature may have less benefits on tests because normally table-driven tests is enough. It will improve your benchmarks 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-benchmarks 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,

--

--

deeeet

Principal YAML engineer at Mercari platform group. https;://twitter.com/deeeet