我正在玩 Go 中的基准测试,我有一个简单的函数,它只休眠 5 纳秒,但是当我运行基准测试时,它显示298.1 ns/op. 我很好奇为什么会这样。不应该5 ns/op吗?去版本:go version go1.19 linux/amd64代码:package andreiimport ( "testing" "time")func Hi() { time.Sleep(5 * time.Nanosecond)}func BenchmarkHi(b *testing.B) { for i := 0; i < b.N; i++ { Hi() }}结果:$ go test -run none -bench . -benchmem ./andreigoos: linuxgoarch: amd64pkg: andrei/andreicpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHzBenchmarkHi-8 3861392 298.1 ns/op 0 B/op 0 allocs/opPASSok andrei/andrei 1.470s
2 回答
呼啦一阵风
TA贡献1802条经验 获得超6个赞
time.Sleep
只保证它至少会睡到参数一样长的时间。它实际休眠多长时间取决于您的操作系统和其他因素。
在 Windows 上,它至少休眠 1.9 毫秒。在我的 MacBook 上,我得到 408 ns/op,而你看到的是 298.1 ns/op。
您可以在 Go github 存储库中的这张票中找到有关此问题的更多详细信息:
https://github.com/golang/go/issues/29485
慕盖茨4494581
TA贡献1850条经验 获得超11个赞
文章“ How to Write Accurate Benchmarks in Go ”(Teiva Harsanyi,2022 年 8 月)和基准维基页面都提到perflock
(在 Linux 上):
我们应该确保执行基准测试的机器是空闲的。但是,外部进程可能会在后台运行,这可能会影响基准测试结果。
出于这个原因,诸如 之类的工具
perflock
可以限制基准测试可以消耗多少 CPU。例如,我们可以使用总可用 CPU 的 70% 运行基准测试,将 30% 分配给操作系统和其他进程,并减少机器活动因素对结果的影响。
另请参阅“问题 44343::runtime
比time.Sleep
预期花费更多时间”。
对于 Linux,我们应该使用
epoll_pwait2
,例如https://go.dev/cl/363417。
这个系统调用是较新的,但这将改进未来的事情并为特别受影响的用户提供解决方法(升级内核)。
- 2 回答
- 0 关注
- 103 浏览
添加回答
举报
0/150
提交
取消