Skip to content

Commit b41c4c3

Browse files
authored
Merge pull request #890 from devlights/add-go124-benchmark-loop-example
2 parents 5ea8980 + efe0851 commit b41c4c3

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# https://taskfile.dev
2+
3+
version: '3'
4+
5+
tasks:
6+
default:
7+
cmds:
8+
- go test -bench . -benchmem
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func setup() {
9+
time.Sleep(1 * time.Second)
10+
}
11+
12+
func slowFn() {
13+
time.Sleep(100 * time.Millisecond)
14+
}
15+
16+
func Benchmark_OldStyleLoop_NoResetTimer(b *testing.B) {
17+
setup()
18+
19+
for range b.N {
20+
slowFn()
21+
}
22+
23+
b.Logf("N: %d", b.N)
24+
}
25+
26+
func Benchmark_OldStyleLoop_WithResetTimer(b *testing.B) {
27+
setup()
28+
b.ResetTimer() // セットアップの時間を含めないようここでタイマーをリセット
29+
30+
for range b.N {
31+
slowFn()
32+
}
33+
34+
b.Logf("N: %d", b.N)
35+
}
36+
37+
func Benchmark_NewStyleLoop(b *testing.B) {
38+
//
39+
// Go 1.24 にて、testing.B.Loop が追加された。
40+
// シグネチャは以下の様になっている。
41+
//
42+
// func (b *B) Loop() bool
43+
//
44+
// 以前までは、testing.B.N を使用してループすることで
45+
// ベンチマークを計測していたが、今後は testing.B.Loop を
46+
// 使用してベンチマークすることが推奨されるようになる。
47+
//
48+
// testing.B.Loop を使用することで以下の恩恵がある。
49+
//
50+
// - ベンチマーク関数が1回のみ実行されるようになる
51+
// - セットアップやクリーンアップの回数が減少
52+
// - b.Loop を利用しているループはコンパイラの最適化がかからないようになる
53+
// - b.Loop の開始と終了時にタイマーが自動管理されるようになる
54+
// - b.ResetTimer() の呼び出しが不要となる
55+
// - セットアップコードがベンチマーク時間に含まれなくなる
56+
//
57+
// # REFERENCES
58+
// - https://pkg.go.dev/testing@go1.24.0#hdr-b_N_style_benchmarks
59+
// - https://pkg.go.dev/testing@go1.24.0#B.Loop
60+
// - https://antonz.org/go-1-24/#benchmark-loop
61+
// - https://www.bytesizego.com/blog/go-124-new-benchmark-function
62+
//
63+
64+
// セットアップコードは1度だけ呼び出される
65+
setup()
66+
67+
// b.Loop を利用する場合、内部でタイマーの自動管理が行われるので
68+
// b.ResetTimer() の呼び出しが不要となる
69+
//
70+
// - b.Loop の開始時に b.ResetTimer() される
71+
// - b.Loop が false を返したときに b.StopTimer() される
72+
for b.Loop() {
73+
//
74+
// for b.Loop() { ... } の中は決して最適化が行われない
75+
//
76+
slowFn()
77+
}
78+
79+
b.Logf("N: %d", b.N)
80+
}

0 commit comments

Comments
 (0)