不是缓存问题;go test -bench=. 每次真实运行,不依赖缓存,go clean -testcache 对其无效;“没变”或“0 ns/op”主因是函数签名错误、未用b.N循环或初始化误入计时区。

go test -bench 的结果不刷新,是不是缓存问题?
不是。Go 的 go test -bench=. 本身不缓存执行结果——它每次都会真实运行被测函数,输出的 ns/op 和 allocs/op 是实测值。你看到“没变”或“跳过”,通常是因为:被测函数没被真正执行(比如签名错误、循环写死、初始化误入计时区),或者你误把 go test -run=.(单元测试)的 -testcache 行为套用到了基准测试上。
go clean -testcache 对 Benchmark 有没有用?
完全没用。go clean -testcache 只影响 go test 对**单元测试通过状态**的缓存判断(即是否显示 “cached”),它不碰任何基准测试逻辑、不删计时数据、不干预 b.N 循环行为。Benchmark 的执行全程绕过该缓存机制。即使你刚执行过 go clean -testcache,go test -bench=. 依然会照常跑满所有迭代,只是单元测试部分可能重跑而已。
那 Benchmark 输出“卡住”或“0 ns/op”到底怎么修?
这是真问题,常见于 CodeGeex 或手动写的 benchmark 函数。必须检查以下三点:
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
-
函数签名是否为
func BenchmarkXxx(b *testing.B)—— 缺*(指针)或写成*testing.T,go test -bench=.会直接忽略该函数,不报错也不输出 -
循环是否用了
b.N—— 写成for i := 0; i 就是硬编码,b.N不生效,结果恒为0 ns/op;正确写法是for i := 0; i -
初始化代码是否在计时区内 —— 比如
m := make(map[int]int)写在for循环里,测的就不是查找而是建 map 开销;应移到循环外,并在重置后调用b.ResetTimer()(或更稳妥的b.StopTimer()/b.StartTimer())
GoLand 里还有哪些干扰项要关掉?
GoLand 自身不会缓存 benchmark 输出,但它可能因自动构建或语言服务干扰你的调试节奏:
- 关掉 Settings → Go → Build Tags & Vendoring → Build project automatically,避免保存即触发
go list扫描,间接污染$GOCACHE - 检查 Settings → Tools → File Watchers,禁用所有 Go 相关 watcher,防止它们在后台静默跑
go test -short类命令 - 确认 Settings → Go → Language Server → Build Ignore Patterns 包含
**/testdata/**和**/*_test.go,避免 gopls 对 benchmark 文件做无谓分析
真正需要清理的只有 $GOCACHE(用 go clean -cache),但那是为了排除编译中间产物复用导致的逻辑未更新,和 benchmark 输出“不变”无直接因果关系。










