Golangでのベンチマークテストの書き方
Go「プログラミング言語Go」の練習問題1.3の解答を作成してみました。スライスに含まれる文字列(strings
)を連結する方法として、ループによる方法と strings.Join
を使う方法のそれぞれの実行時間を計測するため、ベンチマークテストを作成します。コードは以下の通りです。(main.go の方の main関数は、ベンチマークテストには不要です。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// Exercise 1.3 (p.9) // for benchmark: // $ go test -bench=. // $ go test -bench=SlicePrintLoop // $ go test -bench=SlicePrintJoin package main import ( "strings" ) func SlicePrintLoop(argslice []string) { s, sep := "", "" for _, arg := range argslice { s += sep + arg sep = " " } } func SlicePrintJoin(argslice []string) { strings.Join(argslice, " ") } func main() { slc := []string{"hello", "world"} SlicePrintLoop(slc) SlicePrintJoin(slc) } </pre> <pre class="lang:go decode:true " title="main_test.go" >package main import "testing" var slc []string func init() { for i := 0; i < 1000; i++ { slc = append(slc, "a") } } func BenchmarkSlicePrintLoop(b *testing.B) { for i := 0; i < b.N; i++ { SlicePrintLoop(slc) } } func BenchmarkSlicePrintJoin(b *testing.B) { for i := 0; i < b.N; i++ { SlicePrintJoin(slc) } } |
ベンチマークテストを実行するには、これらのファイルのあるディレクトリで、以下のコマンドを実行します。
1 |
$ go test -bench=. |
しばらくすると、以下のような結果が出力されます。
1 2 3 4 |
BenchmarkSlicePrintLoop-2 5000 287222 ns/op BenchmarkSlicePrintJoin-2 200000 10510 ns/op PASS ok exercises-gopl/1.3 3.691s |
今回は、1000個の文字列からなるスライスでベンチマークテストを行いましたが、ループによる方法よりも strings.Join
を使う方法の方が27倍ほど速いことがわかります。
以上、簡単な例でしたが、ベンチマークテストのわかりやすい例だと思います。
参考文献
- 「プログラミング言語Go」 Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)