用 go test -bench=^benchmarkfuncname$ 可精确运行单个基准测试函数,需确保函数名导出、签名正确(func(b *testing.b))且位于匹配包的 _test.go 文件中。

如何用 go test -bench 只跑某个 Benchmark 函数
直接指定函数名就能精准运行,不需要改代码或写额外逻辑。go test -bench 默认匹配所有以 Benchmark 开头的函数,但支持正则匹配,所以最常用的方式是:
- 运行单个:
go test -bench=^BenchmarkMyFunc$(^和$保证精确匹配,避免误中BenchmarkMyFuncParallel) - 运行一组:
go test -bench=^BenchmarkJSON(匹配所有以BenchmarkJSON开头的函数) - 注意:不加
-bench参数时,go test完全忽略基准测试函数,哪怕它存在也不会执行
为什么加了 -bench 却没输出结果
常见原因是函数签名不对或未导出。Go 的基准测试函数必须严格满足两个条件:
- 函数名以
Benchmark开头,且首字母大写(即导出) - 签名必须是
func(b *testing.B),不能多参数、不能返回值、不能是方法 - 如果函数在
xxx_test.go文件里但包名不是main或对应包名(比如写成package helper),go test会跳过它 —— 测试文件的 package 必须和被测代码一致(或为main)
典型错误示例:func BenchmarkFoo(t *testing.T)(用了 *testing.T)或 func benchmarkBar(b *testing.B)(小写开头)都不会被识别。
如何让 Benchmark 只跑一次或控制迭代次数
testing.B 本身不提供“只跑一次”的开关,但你可以通过 b.N 手动干预循环逻辑,或者用 b.ResetTimer() / b.StopTimer() 控制计时区段:
-
b.N是框架自动设置的迭代次数(通常从 1 开始指数增长直到稳定),你**不应直接赋值b.N = 1**,否则会破坏基准逻辑,导致ns/op计算失真 - 若真要观察单次行为(比如调试初始化开销),可临时改用
fmt.Println+time.Now(),而非依赖go test -bench - 真正可控的是最小采样时间:
go test -bench=. -benchtime=100ms,这会让每轮基准至少运行 100 毫秒,影响最终b.N的取值
并行基准测试(BenchmarkParallel)怎么触发
Go 不提供 BenchmarkParallel 这样的内置函数名;并行能力由 b.RunParallel 提供,但它必须在标准 BenchmarkXXX 函数体内调用:
func BenchmarkSortParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
sort.Ints(data)
}
})
}
运行方式和其他基准一样:go test -bench=BenchmarkSortParallel。注意:b.RunParallel 内部会自动分配 goroutine,无需手动 go 启动;也不建议在外层再套 go,会导致 b.N 统计错乱。
最容易被忽略的一点:如果被测逻辑本身有共享状态(比如全局 map、缓存),RunParallel 下并发读写会引发 panic 或数据竞争 —— 运行时加上 -race 很有必要。











