如何在不到一纳秒的 Go 中计时?
How to time something in Go, which takes less than a nanosecond?
如果我想比较两个函数的时间,但函数用时不到一纳秒,我该如何进行?
t := time.Now()
_ = fmt.Sprint("Hello, World!")
d := time.Since(t)
d.Round(0)
fmt.Println(d.Nanoseconds()) // Prints 0
我可以 运行 该函数几次,然后将时间除以执行次数,但我更喜欢一种为单次执行计时的方法。有办法吗?
如果计时函数生成的时间小于纳秒,通常意味着代码已被优化。
编译器可以检测到某些代码没有副作用,并决定“我为什么要那样做”。
1/(1 ns) 为 1 Ghz。现代台式计算机的上限约为 5 Ghz,或多或少。因此,要小于 1 ns,操作加上获取时间的开销必须少于 5 CPU 个周期。在那个级别的分辨率下,CPU 不是一次只做一件事。一条指令的开始和结束可以相隔多个周期,操作是流水线的。
所以你必须查看机器代码并了解架构才能确定真正的成本是多少,包括 CPU 的资源的哪些部分被使用,以及它如何与其他操作冲突你可能想在附近做。
因此,即使“之前”和“之后”在大多数 CPU 秒的亚 1 纳秒时间分辨率下也不再具有合理的意义,速度足以 运行 高于 1 Ghz。
你可以做的是回答“这件事之前跑了多少次”这个问题
至少需要一纳秒":
package main
import (
"fmt"
"time"
)
func main() {
d := 1
for {
t := time.Now()
for e := d; e > 0; e-- {
fmt.Sprint("Hello, World!")
}
if time.Since(t) > 0 { break }
d *= 2
}
println(d)
}
如果我想比较两个函数的时间,但函数用时不到一纳秒,我该如何进行?
t := time.Now()
_ = fmt.Sprint("Hello, World!")
d := time.Since(t)
d.Round(0)
fmt.Println(d.Nanoseconds()) // Prints 0
我可以 运行 该函数几次,然后将时间除以执行次数,但我更喜欢一种为单次执行计时的方法。有办法吗?
如果计时函数生成的时间小于纳秒,通常意味着代码已被优化。
编译器可以检测到某些代码没有副作用,并决定“我为什么要那样做”。
1/(1 ns) 为 1 Ghz。现代台式计算机的上限约为 5 Ghz,或多或少。因此,要小于 1 ns,操作加上获取时间的开销必须少于 5 CPU 个周期。在那个级别的分辨率下,CPU 不是一次只做一件事。一条指令的开始和结束可以相隔多个周期,操作是流水线的。
所以你必须查看机器代码并了解架构才能确定真正的成本是多少,包括 CPU 的资源的哪些部分被使用,以及它如何与其他操作冲突你可能想在附近做。
因此,即使“之前”和“之后”在大多数 CPU 秒的亚 1 纳秒时间分辨率下也不再具有合理的意义,速度足以 运行 高于 1 Ghz。
你可以做的是回答“这件事之前跑了多少次”这个问题 至少需要一纳秒":
package main
import (
"fmt"
"time"
)
func main() {
d := 1
for {
t := time.Now()
for e := d; e > 0; e-- {
fmt.Sprint("Hello, World!")
}
if time.Since(t) > 0 { break }
d *= 2
}
println(d)
}