benchstat 需单独安装,属 golang.org/x/perf/cmd/benchstat;解析要求纯文本、标准格式输出,避免 ansi 色彩与杂日志;默认用几何平均汇总,关键看具体函数行而非顶部 geomean。

benchstat 命令没找到,但 go test -bench 已跑出结果
说明 benchstat 不是 Go 标准命令,得单独安装。它属于 golang.org/x/perf/cmd/benchstat,不是 go 自带的二进制。
实操建议:
- 运行
go install golang.org/x/perf/cmd/benchstat@latest(Go 1.21+ 推荐加@latest) - 确认
$GOPATH/bin在$PATH中,否则 shell 找不到benchstat - 如果用 Go 1.20 或更早,需先
go get,但注意:go get在 1.17+ 已不推荐用于安装命令,容易漏更新 - 装完可跑
benchstat -h确认是否可用;若报command not found,大概率是 PATH 没配对
benchstat 报错 “no benchmark results found”
这是最常卡住的地方:它只认标准 go test -bench 输出格式,且要求输入是纯文本、无额外日志或 ANSI 颜色。
常见错误现象:
立即学习“go语言免费学习笔记(深入)”;
- 把
go test -bench . -count=5 2>&1 | tee bench-old.txt的输出直接喂给benchstat,但终端颜色码(如\x1b[32m)会让解析失败 - 在 CI 日志里复制了一段带时间戳/前缀的输出,
benchstat无法识别 - 文件末尾多了一个空行或注释行,它会跳过整块
实操建议:
- 务必用
go test -bench . -count=5 -benchmem > bench-old.txt直接重定向,别走2>&1或管道 - 检查文件头几行是否为
goos: linux、goarch: amd64、BenchmarkXXX-8 1000000 1234 ns/op这种格式,缺一不可 - 用
cat -A bench-old.txt查看是否有隐藏字符;有就用sed 's/\x1b\[[0-9;]*m//g' bench-old.txt > clean.txt清理
对比两个版本时,benchstat 显示 “geomean: +0.00%” 但单个函数涨了 15%
说明 benchstat 默认用几何平均(geomean)汇总所有 benchmark,而某个函数耗时突增可能被其他大量低耗时 benchmark 平滑掉。
使用场景:
- 你改的是
BenchmarkParseJSON,但它只占全部 5 个 benchmark 中的 1 个,其余 4 个几乎没变 -
benchstat old.txt new.txt输出顶部显示整体变化微小,但下面表格里BenchmarkParseJSON行明确标出+15.23%
实操建议:
- 永远先扫一眼表格中具体函数那一行,别只信顶部的 geomean
- 加
-delta-test=p参数让benchstat做显著性检验(如p ),避免把噪声当真实提升 - 如果只想看某几个函数,用
benchstat -geomean=false old.txt new.txt关掉汇总,或配合grep BenchmarkParseJSON提取关键行
Go 1.21+ 的 -benchtime 和 -count 对 benchstat 结果影响很大
参数差异直接影响统计稳定性:-count 决定重复次数(默认 1),-benchtime 决定单次运行目标时长(默认 1s)。两者共同决定数据点数量和方差。
性能 / 兼容性影响:
-
-count=1时,哪怕两次运行环境完全一致,benchstat也认为“无统计意义”,不显示 delta 百分比 -
-benchtime=100ms可能导致单次运行太短、测量误差放大,尤其在低开销函数上 - Go 1.21 起默认启用
-benchmem,但旧版没开的话,内存分配数不会被benchstat对比——容易误判优化效果
实操建议:
- 统一用
go test -bench . -benchmem -count=5 -benchtime=2s,确保每次至少跑满 2 秒、重复 5 轮 - 两次对比必须用完全相同的参数组合,否则
benchstat会拒绝比较(报inconsistent benchmarks) - CI 中建议固定
GOMAXPROCS=1和关闭 CPU 频率调节,否则-count=5的方差可能大到掩盖真实变化
真正难的不是跑出数字,而是让两次 go test -bench 输出在统计意义上可比——环境、参数、甚至 CPU 温度,都会悄悄改写结果。别信单次运行,也别跳过 -count。










