関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。忘れないようにここにメモメモ。。。
Go 1.24で testing.B.Loop() が追加されました。
これまでは、testing.B.N を使用してループで回していたものが、今後は
for b.Loop() {
}
と書けるようになります。簡易に書けるようになっただけではなく以下のような効能もあります。
- ベンチマーク関数が1回だけ実行されるようになる
b.Loop()のループ内は決して最適化されないようになるb.Loop()の開始と終了時に自動的にタイマーの管理が行われるのでb.ResetTimer()の呼び出しが不要になる
より正確にベンチマークを測定できるようになるので、使わない手は無いです。
サンプル
a_test.go
package main import ( "testing" "time" ) func setup() { time.Sleep(1 * time.Second) } func slowFn() { time.Sleep(100 * time.Millisecond) } func Benchmark_OldStyleLoop_NoResetTimer(b *testing.B) { setup() for range b.N { slowFn() } b.Logf("N: %d", b.N) } func Benchmark_OldStyleLoop_WithResetTimer(b *testing.B) { setup() b.ResetTimer() // セットアップの時間を含めないようここでタイマーをリセット for range b.N { slowFn() } b.Logf("N: %d", b.N) } func Benchmark_NewStyleLoop(b *testing.B) { // // Go 1.24 にて、testing.B.Loop が追加された。 // シグネチャは以下の様になっている。 // // func (b *B) Loop() bool // // 以前までは、testing.B.N を使用してループすることで // ベンチマークを計測していたが、今後は testing.B.Loop を // 使用してベンチマークすることが推奨されるようになる。 // // testing.B.Loop を使用することで以下の恩恵がある。 // // - ベンチマーク関数が1回のみ実行されるようになる // - セットアップやクリーンアップの回数が減少 // - b.Loop を利用しているループはコンパイラの最適化がかからないようになる // - b.Loop の開始と終了時にタイマーが自動管理されるようになる // - b.ResetTimer() の呼び出しが不要となる // - セットアップコードがベンチマーク時間に含まれなくなる // // # REFERENCES // - https://pkg.go.dev/testing@go1.24.0#hdr-b_N_style_benchmarks // - https://pkg.go.dev/testing@go1.24.0#B.Loop // - https://antonz.org/go-1-24/#benchmark-loop // - https://www.bytesizego.com/blog/go-124-new-benchmark-function // // セットアップコードは1度だけ呼び出される setup() // b.Loop を利用する場合、内部でタイマーの自動管理が行われるので // b.ResetTimer() の呼び出しが不要となる // // - b.Loop の開始時に b.ResetTimer() される // - b.Loop が false を返したときに b.StopTimer() される for b.Loop() { // // for b.Loop() { ... } の中は決して最適化が行われない // slowFn() } b.Logf("N: %d", b.N) }
Taskfile.yml
# https://taskfile.dev version: '3' tasks: default: cmds: - go test -bench . -benchmem
shell
実行すると以下のように出力されます。
$ task task: [default] go test -bench . -benchmem goos: linux goarch: amd64 pkg: github.com/devlights/try-golang/examples/testing/go124_benchmark_loop cpu: AMD EPYC 7B13 Benchmark_OldStyleLoop_NoResetTimer-16 1 1100764848 ns/op 3496 B/op 17 allocs/op --- BENCH: Benchmark_OldStyleLoop_NoResetTimer-16 a_test.go:23: N: 1 Benchmark_OldStyleLoop_WithResetTimer-16 10 100213149 ns/op 336 B/op 1 allocs/op --- BENCH: Benchmark_OldStyleLoop_WithResetTimer-16 a_test.go:34: N: 1 a_test.go:34: N: 10 Benchmark_NewStyleLoop-16 10 100190719 ns/op 0 B/op 0 allocs/op --- BENCH: Benchmark_NewStyleLoop-16 a_test.go:79: N: 10 PASS ok github.com/devlights/try-golang/examples/testing/go124_benchmark_loop 6.213s
ちゃんと一度だけの呼び出しになっていますね。
参考情報
Go 1.24's New Benchmark Function; a better way to benchmark
testing package - testing - Go Packages
testing package - testing - Go Packages
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。





