基准测试函数必须放在以_test.go结尾的文件中,且签名须为func benchmarkxxx(b *testing.b),并调用b.resettimer()以排除初始化开销。

基准测试函数必须放在 *_test.go 文件里
不放对位置,go test -bench=. 就根本不会发现你的 BenchmarkXxx 函数。Go 测试框架只扫描以 _test.go 结尾的文件,且只执行函数名以 Benchmark 开头、参数为 *testing.B 的函数。
常见错误现象:
- 写了
BenchmarkFoo,但运行go test -bench=.输出为空 - 把基准测试写在普通
.go文件里,或写在main.go中 - 函数签名写成
func BenchmarkFoo(t *testing.T)(用了*testing.T)
正确做法:
- 新建
utils_test.go或stringutil_test.go等文件 - 导入
"testing" - 函数定义严格为
func BenchmarkFoo(b *testing.B)
b.ResetTimer() 一定要在初始化之后、循环之前调用
否则预处理(如切片构造、变量初始化)的时间会被计入最终 ns/op,导致结果虚高、不可比。比如你创建一个含 10000 个元素的切片再求和,若没重置计时器,那内存分配和赋值时间全算进去了。
典型错误写法:
func BenchmarkSum(b *testing.B) {
data := make([]int, 10000)
for i := range data {
data[i] = i
}
for i := 0; i
<p>这段代码测的其实是「初始化 + 求和」,不是纯求和性能。</p>
<p>正确写法:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0"><img
src="https://img.php.cn/upload/manual/001/589/237/6a6adeed24a4a355.png" alt="Go语言(Golang)1.26.0" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="overflowclass">Go语言(Golang)1.26.0</a>
<p class="overflowclass">Go语言(Golang)1.26.0版本官方下载,版本号 1.26.0,适合旧项目维护、兼容性测试和指定版本开发环境搭建。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;">func BenchmarkSum(b *testing.B) {
data := make([]int, 10000)
for i := range data {
data[i] = i
}
b.ResetTimer() // ← 关键:从此刻开始计时
for i := 0; i
<h3>对比不同实现时,要保证输入数据完全一致</h3>
<p>比如比较 <code>strings.Join</code> 和 <code>+=</code> 拼接字符串,如果一个用 <code>[]string{"a","b","c"}</code>,另一个用 <code>[]string{"x","y","z"}</code>,或者长度不同,那结果毫无可比性。</p>
<p>实操建议:</p>
- 所有待测函数共用同一份输入数据(定义在
Benchmark函数顶部) - 避免在循环内重新生成输入,防止引入额外开销
- 若需多组输入(如不同长度),应分别写多个
Benchmark函数,命名体现差异,例如BenchmarkJoin_10Elements、BenchmarkJoin_100Elements - 对引用类型(如
map、struct),注意是否被修改;必要时用copy或重建副本
运行时加 -benchmem 和 -count=3 才算靠谱
默认 go test -bench=. 只输出 ns/op,但内存分配(B/op、allocs/op)往往才是性能瓶颈根源;单次运行还可能受 CPU 频率波动、后台任务干扰影响。
推荐命令:
go test -bench=. -benchmem -count=3
含义:
-
-benchmem:显示每次操作分配多少字节、多少次堆分配 -
-count=3:重复运行 3 轮,取中位数或观察波动范围(go test默认只跑 1 轮) - 可追加
-benchtime=2s让每轮至少跑满 2 秒,提升b.N稳定性
真正容易被忽略的是:即使 ns/op 差不多,allocs/op 高一倍,长期运行就可能引发更多 GC 停顿——这点在服务端程序里比耗时更致命。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










