贝利信息

Golang基准测试Benchmark Test的基本写法

日期:2026-01-24 00:00 / 作者:P粉602998670
Go基准测试函数名必须以Benchmark开头,定义在_test.go文件中,仅接收*testing.B参数且无返回值,主体需用b.N循环并调用b.Res

etTimer()。

Go基准测试函数名必须以Benchmark开头

Go的testing包只识别形如BenchmarkXXX的函数为基准测试,且必须接收*testing.B参数。名字不满足规则(比如写成TestBenchmarkbenchFoo)会导致go test -bench完全忽略该函数。

常见错误:把基准测试和普通单元测试混写在同一文件但没注意命名规范,结果-bench=.跑出来是no benchmarks to run

基准测试主体必须调用b.N循环

*testing.Bb.N不是固定次数,而是由Go测试框架根据预热和稳定性自动确定的迭代次数。你必须在b.ResetTimer()之后、实际测量代码里显式使用for i := 0; i 包裹待测逻辑,否则测的是0次或1次,结果无意义。

容易踩的坑:直接在循环外执行一次操作,或者用b.ReportAllocs()但忘了加循环——这时b.N可能是1,所有耗时/内存数据都失真。

运行基准测试必须加-bench参数

go test默认不运行任何Benchmark函数,必须显式传参。最常用的是go test -bench=.(点号表示匹配所有),也可以用正则精确指定,比如go test -bench=BenchmarkJSON

注意:-bench会自动启用-cpuprofile等底层支持,但不会运行Test函数——除非同时加-run。这点常被忽略,导致误以为“基准测试失败”其实是没跑起来。

func BenchmarkAdd(b *testing.B) {
    var x, y = 1, 2
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _ = x + y
    }
}

这个例子看起来简单,但漏掉b.ResetTimer()或没用b.N循环,就不是有效的基准测试。真实场景中,初始化DB连接、构建大结构体、预热缓存这些动作,都需要仔细安排在计时开关之间。