Golangで数を増やしながらベンチマーク

ベンチマークを測定していると要素数を増やしたり、負荷を上げたりしながら性能がどのように変わるか調べたいときがあります。 変数をべた書きしたベンチマークをコピペして書くことも可能ですが、以下のような方法できれいに書くことができます。

ここでは関数doSomething()ベンチマークを取りたいとします。

package multibench

func doSomething(n int) {}

以下のようにテストファイルの中に、要素数nを引数とする関数を、補助的に用意することで目的が達成できます。ここでbenchmarkDoSomething()はpackage内でのみ参照できればいいので、小文字から始まることに注意してください。逆に測定したいBenchmarkDoSomething10()などは、大文字から始まります。

package multibench

import "testing"

func benchmarkDoSomething(n int, b *testing.B) {
    for i := 0; i < b.N; i++ {
        doSomething(n)
    }
}

func BenchmarkDoSomething10(b *testing.B)   { benchmarkDoSomething(10, b) }
func BenchmarkDoSomething30(b *testing.B)   { benchmarkDoSomething(30, b) }
func BenchmarkDoSomething70(b *testing.B)   { benchmarkDoSomething(70, b) }
func BenchmarkDoSomething100(b *testing.B)  { benchmarkDoSomething(100, b) }
func BenchmarkDoSomething300(b *testing.B)  { benchmarkDoSomething(300, b) }
func BenchmarkDoSomething700(b *testing.B)  { benchmarkDoSomething(700, b) }
func BenchmarkDoSomething1000(b *testing.B) { benchmarkDoSomething(1000, b) }
func BenchmarkDoSomething3000(b *testing.B) { benchmarkDoSomething(3000, b) }

実行結果

$ go test -bench DoSomething
BenchmarkDoSomething10-4        2000000000           0.33 ns/op
BenchmarkDoSomething30-4        2000000000           0.34 ns/op
BenchmarkDoSomething70-4        2000000000           0.33 ns/op
BenchmarkDoSomething100-4       2000000000           0.35 ns/op
BenchmarkDoSomething300-4       2000000000           0.33 ns/op
BenchmarkDoSomething700-4       2000000000           0.33 ns/op
BenchmarkDoSomething1000-4      2000000000           0.34 ns/op
BenchmarkDoSomething3000-4      2000000000           0.34 ns/op
PASS
ok      /YOURPATH/TO/multibench 5.680s

doSomeshingというよりdoNothingなので変化がわかりづらいですが、 関数の中身がnによって変化するようなものであればちゃんと変わります。

References