testing.Bによるベンチマークの作成
BenchmarkXxx、b.Nループ、-benchフラグ
「testing.Bによるベンチマークの作成」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
ベンチマーク関数のシグネチャ
ベンチマークはBenchmarkで始まり、*testing.Bを受け取ります。通常のテストと同じく、_test.goファイルに記述します。
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}b.N
テストフレームワークはb.N、つまりループの反復回数を自動的に調整し、ベンチマークが少なくとも1秒間実行されるようにします。これにより、安定した1操作あたりのナノ秒数が得られます。
ベンチマークの実行
ベンチマークはgo testだけでは実行されません。-benchを指定して有効にします:
go test -bench=. -benchmem ./...
// BenchmarkAdd-8 500000000 2.13 ns/op 0 B/op 0 allocs/op-benchmemフラグ
-benchmemを指定すると、アロケーションの統計情報、つまり1操作あたりのバイト数とアロケーション数が追加されます。アロケーションが多い場合は、パフォーマンス上の問題があることがよくあります。
b.ResetTimer
ベンチマークの計測対象に含めない高コストなセットアップの後で、b.ResetTimer()を呼び出します:
func BenchmarkQuery(b *testing.B) {
db := setupDB() // expensive
b.ResetTimer()
for i := 0; i < b.N; i++ {
db.Query("SELECT 1")
}
}b.StopTimer / b.StartTimer
ベンチマーク時間に含めないセットアップやティアダウンの前後で、タイマーを一時停止・再開します。
for i := 0; i < b.N; i++ {
b.StopTimer()
data := generateInput()
b.StartTimer()
process(data)
}b.SetBytes
時間あたりの処理量に相当するスループット(バイト/秒)を、time/opに加えてレポートするにはb.SetBytes(n)を呼び出します。シリアライズやネットワークコードのベンチマークに便利です。
b.SetBytes(int64(len(payload)))
for i := 0; i < b.N; i++ {
encode(payload)
}ベンチマークの比較
2回のベンチマーク実行結果を比較し、統計的に有意な差を確認するにはbenchstatを使います:
go test -bench=. -count=10 > before.txt
# make change
go test -bench=. -count=10 > after.txt
benchstat before.txt after.txtデッドコード除去の防止
コンパイラがベンチマーク対象のコードを最適化で除去しないように、結果をパッケージレベルの変数またはシンクに代入します:
var result int
func BenchmarkFib(b *testing.B) {
for i := 0; i < b.N; i++ {
result = Fib(20)
}
}サブベンチマーク
テーブル駆動テストと同様に、名前付きのサブベンチマークを作成するにはb.Runを使います:
for _, size := range []int{10, 100, 1000} {
b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
for i := 0; i < b.N; i++ { sort(make([]int, size)) }
})
}ベンチマークとプロファイリング
ベンチマークはパフォーマンスを数値化します。プロファイリング(pprof)は時間がどこで使われているかを示します。測定にはベンチマークを使い、最適化すべき箇所の特定にはプロファイリングを使います。
クイックチェック
コンパイラによる最適化を防ぐために、ベンチマークのループ本体で結果を使用しなければならないのはなぜですか?
まとめ: ベンチマーク
重要事項:
- BenchmarkXxx(b *testing.B)で、for i := 0; i < b.N; i++の形式を使います
- go test -bench=. -benchmemでアロケーションの統計情報を取得します
- 高コストなセットアップの後でb.ResetTimer()を使います
- benchstatで実行結果を比較し、除去を防ぐために結果を代入します
よくある質問
「testing.Bによるベンチマークの作成」レッスンは無料ですか?
はい。「testing.Bによるベンチマークの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「testing.Bによるベンチマークの作成」で何を学びますか?
BenchmarkXxx、b.Nループ、-benchフラグ ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「testing.Bによるベンチマークの作成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- testing.Bによるベンチマークの作成
- pprofによるCPUプロファイリング
- ヒープとメモリ割り当てのプロファイリング
- 実行トレース