Following benchmark example tests in golang, I could for examlpe have this test:
// An example benchmark to benchmark a query based on different inputs
func Benchmark_GetProcessingCountForRegions(b *testing.B) {
benchmarks := []struct {
region string
}{
{"EU"},
{"US"},
}
for _, bm := range benchmarks {
b.Run(bm.region, func(bbb *testing.B) {
for i := 0; i < bbb.N; i++ {
taskDb.GetProcessingCountForRegion(bm.region)
}
})
}
}
This is following default examples from the web and works for me; testing the taskDb package for performance on the GetProcessingCountForRegion query.
However for readability of this test I'm trying to extract the inside func, the one that sits inside b.Run(), like so, first extract the func and put it aside:
func GetProcessingCountForRegion(testingB *testing.B, region string) {
for i := 0; i < testingB.N; i++ {
taskDb.GetProcessingCountForRegion(region)
}
}
and then use this func in the actual testfunc like so:
for _, bm := range benchmarks {
b.Run(bm.region, GetProcessingCountForRegion(*b, bm.region))
}
However this gives a compile error: cannot use *b (type testing.B) as type *testing.B in argument to GetProcessingCountForRegion
removing the * from *b, gives the following compile error: GetProcessingCountForRegion(b, bm.region) used as value
So what I want is remove the func parameter from the B.Run(..) statement.
What am I missing?
I think I found an answer using a 'closure', that is, defining a func that returns a func(*testing.B), that can be used within the b.Run(..., namedMethod)..
Code:
func Benchmark_GetProcessingCountForRegions(b *testing.B) {
benchmarks := []struct {
region string
}{
{"EU"},
{"US"},
}
for _, bm := range benchmarks {
f := GetProcessingCountForRegion(bm.region)
b.Run(bm.region, f)
}
}
// GetProcessingCountForRegion is the closure function
func GetProcessingCountForRegion(region string) func(*testing.B) {
return func(b *testing.B) {
for i := 0; i < b.N; i++ {
taskDb.GetProcessingCountForRegion(region)
}
}
}
For example,
bench_test.go
:
package main
import "testing"
func GetProcessingCountForRegion(region string) int {
return 42
}
func benchmarkGetProcessingCountForRegion(b *testing.B, region string) {
for i := 0; i < b.N; i++ {
GetProcessingCountForRegion(region)
}
}
func BenchmarkGetProcessingCountForRegions(b *testing.B) {
benchmarks := []struct {
region string
}{
{"EU"},
{"US"},
}
for _, bm := range benchmarks {
b.Run(bm.region,
func(b *testing.B) {
benchmarkGetProcessingCountForRegion(b, bm.region)
},
)
}
}
Output:
$ go test -bench=.
BenchmarkGetProcessingCountForRegions/EU-4 2000000000 1.17 ns/op
BenchmarkGetProcessingCountForRegions/US-4 2000000000 1.17 ns/op