benchstat 从 Go 1.21 起默认安装,旧版本需手动 go install golang.org/x/perf/cmd/benchstat@latest;仅解析标准 go test -bench 原始输出,要求格式规范、参数一致、环境可控,且需足够样本量(如 -count=5)才能进行有效统计分析。

benchstat 命令根本没安装?先确认 Go 工具链版本
Go 1.21 起 benchstat 才随 go 命令一起默认安装;低于这个版本会提示 command not found: benchstat。别急着 go install,先跑 go version 看清楚——旧版本升级 Go 更稳妥,而不是单独装一个可能不兼容的二进制。
- Go 1.20 及更早:必须手动安装,运行
go install golang.org/x/perf/cmd/benchstat@latest - Go 1.21+:直接用
benchstat,但注意它不在$PATH里?检查go env GOBIN是否已加入环境变量 - Mac M 系列 + Homebrew 安装的 Go?容易出现
benchstat在/opt/homebrew/bin而非GOBIN,优先以go env GOBIN为准
基准测试输出格式不对,benchstat 解析失败
benchstat 只认标准 go test -bench 输出的原始文本(含 BenchmarkXXX-8 1000000 1234 ns/op 这类行),任何额外打印、重定向截断、或用 -json 都会让它报 no benchmarks to compare 或静默退出。
- 确保保存结果用
go test -bench=. -benchmem > old.txt,不是>>或2>&1混入 stderr - 别用
go test -bench=. | tee result.txt——管道可能触发缓冲,导致末尾几行丢失 - 如果用了
-benchtime=1s等参数,要保证所有对比文件用完全相同的-benchtime和-count,否则benchstat会因样本数不一致而拒绝比较 - Windows 用户注意换行符:用
unix2dos或编辑器转成 LF,CR/LF 混合会导致解析跳行
benchstat 输出里 “Geomean” 是啥?别直接看它下结论
benchstat 默认第一行显示 Geomean(几何平均值),但它只是所有 benchmark 的归一化汇总,掩盖了单个函数的涨跌。比如一个函数快了 50%,另一个慢了 40%,Geomean 可能只显示 “-2%”,让你误判整体优化成功。
- 真正要看的是每行 benchmark 的 delta 列:
±X%后面带p=0.XXX—— p 值小于 0.05 才算统计显著 - 如果某 benchmark 显示
1200ns ± 5% 1100ns ± 8% -8.33% (p=0.12),说明变化不显著,别当真 - 加
-delta-test=equal可强制显示是否“无差异”,比默认的 t-test 更适合判断微小改动是否有实质影响 - 避免只比一次:
go test -bench=. -count=5生成 5 个样本,benchstat才有足够数据做方差分析
想对比不同 CPU 或 GC 设置下的性能?参数得对齐再对齐
哪怕只多开一个 GOGC=100,或者测试机从 idle 切到编译中,benchstat 就可能把噪声当信号。它不帮你控制环境,只负责算数。
立即学习“go语言免费学习笔记(深入)”;
- 固定
GOMAXPROCS:不同机器默认值不同,统一设为GOMAXPROCS=1或明确数值再跑 - 关掉后台干扰:
sudo pmset -a disablesleep 1(macOS)、systemctl stop cron(Linux) - GC 影响大?用
runtime.GC()在每个 Benchmark 函数开头手动触发,或加-gcflags="-l"禁用内联干扰测量 - 别跨机器比:CPU 微架构(如 Intel vs AMD)、频率睿频策略、内存带宽都会让数字不可比;同一台机器、重启后、清空
/tmp和 page cache 再测
真实场景里,最常被忽略的是热身不足和样本量太少——-count=1 的结果连 benchstat 都懒得算 p 值,它直接当单点数据处理。











