0Pricing
Go Academy · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. testing.Bによるベンチマークの作成
  2. pprofによるCPUプロファイリング
  3. ヒープとメモリ割り当てのプロファイリング
  4. 実行トレース
← Go Academyに戻る