使用 testing.B 编写基准测试
BenchmarkXxx、b.N 循环与 -bench 标志
使用 testing.B 编写基准测试 是 CoddyKit 上的免费 Go Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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 秒,从而得到稳定的每操作纳秒数。
运行基准测试
仅运行 go test 不会执行基准测试。请使用 -bench 启用基准测试:
go test -bench=. -benchmem ./...
// BenchmarkAdd-8 500000000 2.13 ns/op 0 B/op 0 allocs/op-benchmem 标志
-benchmem 会添加分配统计信息:每次操作的字节数以及每次操作的分配次数。较高的分配量通常表示存在性能问题。
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
调用 b.SetBytes(n),除了报告每次操作耗时之外,还可以报告吞吐量(字节/秒)。这对于测试序列化或网络代码很有用。
b.SetBytes(int64(len(payload)))
for i := 0; i < b.N; i++ {
encode(payload)
}比较基准测试
使用 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 编写基准测试」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「使用 testing.B 编写基准测试」这节课中我会学到什么?
BenchmarkXxx、b.N 循环与 -bench 标志 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「使用 testing.B 编写基准测试」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 testing.B 编写基准测试
- 使用 pprof 进行 CPU 性能分析
- 堆与内存分配性能分析
- 执行跟踪