メインコンテンツにスキップ
モジュール 9 · レッスン 3 / 5コース内の 43/50~12 min
モジュールのレッスン (3/5)

ベンチマークとプロファイル

機能テストに加えて、go test には ベンチマーク (BenchmarkXxx) が組み込まれており、CPU とメモリのプロファイル (pprof) もサポートされています。すべて外部依存関係なし。

ベンチマークの形状

Go
func BenchmarkSum(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = Sum(2, 3)
    }
}

特徴:

  • 正確な署名: func BenchmarkXxx(b *testing.B)。
  • ループは b.N 反復を実行する必要があります。フレームワークは b.N を自動的に調整し、1 から開始して測定が安定するまで増加します (デフォルトでは約 1 秒)。
  • 結果は ns/op (操作あたりナノ秒)、-benchmem では B/op および allocs/op になります。

代表的なコマンド

Bash
go test -bench=. ./...              # all benchmarks
go test -bench=Sum -benchmem        # only Sum, with memory info
go test -bench=. -benchtime=5s      # each benchmark for 5 seconds
go test -bench=. -cpuprofile=cpu.out # generate a CPU profile

一般的な出力:

Code
BenchmarkSum-8        1000000000        0.31 ns/op

-8 は GOMAXPROCS の値です。 0.31 ns/op は、呼び出しごとの平均時間です。

高価なセットアップ: b.ResetTimer

ループの前に長い準備ステップがある場合は、それを測定から除外します。

Go
func BenchmarkSearch(b *testing.B) {
    data := buildLargeSlice(1_000_000) // expensive
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _ = Search(data, 42)
    }
}

便利なバリエーション:

  • b.StopTimer() / b.StartTimer() — 興味のないフェーズのあたりで測定を一時停止します (ループ内で便利です)。
  • b.ReportAllocs() — -benchmem がなくても割り当てレポートを強制します。

b.Run を使用したベンチマーク テーブル

テスト用の t.Run と同様に、パラメトリック ベンチマーク用の b.Run があります。

Go
func BenchmarkSplit(b *testing.B) {
    for _, size := range []int{10, 1000, 100000} {
        b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
            s := strings.Repeat("a,", size)
            b.ResetTimer()
            for i := 0; i < b.N; i++ {
                _ = strings.Split(s, ",")
            }
        })
    }
}

BenchmarkSplit/n=10-8、BenchmarkSplit/n=1000-8 などの出力行は、スケーリング チャートに最適です。

benchstat を使用した 2 つの実装の比較

Bash
go test -bench=. -count=10 > old.txt
# apply change
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txt

benchstat (golang.org/x/perf/cmd/benchstat 内) は、差の平均、標準偏差、および統計的有意性を計算します。

演習

運動#go.m9.l3.e1
試行回数: 0読み込み中…

Sum(2, 3) を呼び出す b.N 上のループを使用して BenchmarkSum を定義します。

エディターを読み込み中…

3 回の試行後に解決策が利用可能になります

運動#go.m9.l3.e2
試行回数: 0読み込み中…

b.ResetTimer を高価なセットアップの後、ループの前に追加して、セットアップが測定に含まれないようにします。

エディターを読み込み中…

3 回の試行後に解決策が利用可能になります

Quiz#go.m9.l3.e3
準備完了

パッケージ内のすべてのベンチマークを実行するフラグはどれですか?

Go
$ go test ???
回答の選択肢