モジュール 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.txtbenchstat (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 ???