

新闻资讯
技术学院Go 的 go test -bench 可客观复现对比算法性能,需规范编写以 Benchmark 开头的函数,接收 *testing.B 参数并在 b.N 次循环中执行待测逻辑,Go 自动调整 b.N 使总耗时约 1 秒。
用 Go 的 go test -bench 可以客观、可复现地对比不同算法实现的性能,关键在于写对基准测试函数、控制变量、理解结果含义。
基准测试函数必须以 Benchmark 开头,接收 *te 参数,并在
sting.Bb.N 次循环中执行待测逻辑。Go 会自动调整 b.N 使总耗时接近 1 秒,确保统计有效。
示例:对比两种字符串反转实现
func BenchmarkReverseBuiltIn(b *testing.B) {
s := "hello world"
for i := 0; i < b.N; i++ {
_ = reverseBuiltIn(s)
}
}
func BenchmarkReverseManual(b *testing.B) {
s := "hello world"
for i := 0; i < b.N; i++ {
_ = reverseManual(s)
}
}
_ = 抑制返回值,防止编译器优化掉整个调用b.Run 分组测试不同长度(见下文)当需要测试不同输入规模或多种参数组合时,用 b.Run 创建子基准,便于横向比较。
例如对比切片去重在不同长度下的表现:
func BenchmarkDedup(b *testing.B) {
for _, size := range []int{100, 1000, 10000} {
b.Run(fmt.Sprintf("Size%d", size), func(b *testing.B) {
data := make([]int, size)
for i := range data {
data[i] = i % (size / 10) // 制造重复
}
for i := 0; i < b.N; i++ {
_ = dedupMap(data)
}
})
}
}
BenchmarkDedup/Size100-8)-benchmem 同时查看内存分配,避免只看时间忽略 GC 压力执行命令:
go test -bench=^BenchmarkReverse -benchmem -count=3
-bench=^BenchmarkReverse 精确匹配函数名(^ 表示开头)-benchmem 显示每次操作的平均内存分配次数和字节数-count=3 运行 3 轮取平均值,减少噪声影响典型输出:
BenchmarkReverseBuiltIn-8 10000000 124 ns/op 16 B/op 1 allocs/op BenchmarkReverseManual-8 20000000 92.1 ns/op 16 B/op 1 allocs/op
重点关注三列:ns/op(纳秒/次,越小越好)、B/op(字节/次)、allocs/op(内存分配次数/次)。若两个实现 ns/op 相差不足 5%,需结合 allocs/op 和实际场景判断是否值得优化。
真实性能受环境波动影响,需主动控制变量:
sudo cpupower frequency-set -g performance(Linux)runtime.GC() 在每次子 benchmark 前手动触发 GC,减少 GC 时间抖动不复杂但容易忽略。