为什么非常短的时间。睡眠时间比基准测试中要求的时间(大约 300 ns)长?

我正在玩 Go 中的基准测试,我有一个简单的函数,它只休眠 5 纳秒,但是当我运行基准测试时,它显示298.1  ns/op. 我很好奇为什么会这样。不应该5 ns/op吗?


去版本:


go version go1.19 linux/amd64


代码:


package andrei


import (

    "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 ./andrei


goos: linux

goarch: amd64

pkg: andrei/andrei

cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz

BenchmarkHi-8            3861392               298.1 ns/op             0 B/op          0 allocs/op

PASS

ok      andrei/andrei   1.470s


慕容3067478
浏览 142回答 2
2回答

呼啦一阵风

time.Sleep只保证它至少会睡到参数一样长的时间。它实际休眠多长时间取决于您的操作系统和其他因素。在 Windows 上,它至少休眠 1.9 毫秒。在我的 MacBook 上,我得到 408 ns/op,而你看到的是 298.1 ns/op。您可以在 Go github 存储库中的这张票中找到有关此问题的更多详细信息:https://github.com/golang/go/issues/29485

慕盖茨4494581

文章“&nbsp;How to Write Accurate Benchmarks in Go&nbsp;”(Teiva Harsanyi,2022 年 8 月)和基准维基页面都提到perflock(在 Linux 上):我们应该确保执行基准测试的机器是空闲的。但是,外部进程可能会在后台运行,这可能会影响基准测试结果。出于这个原因,诸如 之类的工具perflock可以限制基准测试可以消耗多少 CPU。例如,我们可以使用总可用 CPU 的 70% 运行基准测试,将 30% 分配给操作系统和其他进程,并减少机器活动因素对结果的影响。另请参阅“问题 44343::runtime比time.Sleep预期花费更多时间”。对于 Linux,我们应该使用epoll_pwait2,例如https://go.dev/cl/363417。这个系统调用是较新的,但这将改进未来的事情并为特别受影响的用户提供解决方法(升级内核)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go