在 Go 中保证至少经过一纳秒的最省时方法是啥? time.Sleep(time.Nanosecond) 可能需要几毫秒

Posted

技术标签:

【中文标题】在 Go 中保证至少经过一纳秒的最省时方法是啥? time.Sleep(time.Nanosecond) 可能需要几毫秒【英文标题】:What is the most time efficient way to guarantee at least one nanosecond has elapsed in Go? time.Sleep(time.Nanosecond) can take milliseconds在 Go 中保证至少经过一纳秒的最省时方法是什么? time.Sleep(time.Nanosecond) 可能需要几毫秒 【发布时间】:2021-06-26 01:27:24 【问题描述】:

我有两个函数调用,我想将它们分开至少一纳秒。但我希望延迟尽可能小。

下面的代码显示了一个空的for循环比使用time.Sleep(time.Nanosecond)更有效

有没有更有效的方法来保证至少经过一纳秒?

func TimeWaster () 
    start := uint64(time.Now().UnixNano())
    stop := uint64(time.Now().UnixNano())
    fmt.Println(time.Duration(stop-start))//0s
    //no nanoseconds pass

    start = uint64(time.Now().UnixNano())
    time.Sleep(time.Nanosecond)
    stop = uint64(time.Now().UnixNano())
    fmt.Println(time.Duration(stop-start))//6.9482ms
    //much *much* more than one nanosecond passes

    start = uint64(time.Now().UnixNano())
    for uint64(time.Now().UnixNano()) == start 
        //intentionally empty loop
    
    stop = uint64(time.Now().UnixNano())
    fmt.Println(time.Duration(stop-start))//59.3µs
    //much quicker than time.Sleep(time.Nanosecond), but still much slower than 1 nanosecond

【问题讨论】:

请问你为什么会关心一纳秒已经过去了? 我正在使用一个我无法控制的包。这个包定义了纳秒的唯一性。可悲的是,我可以并且确实在同一纳秒内调用它。所以,我只关心因为一些包关心的原因与时间无关。 【参考方案1】:

您正在使用的包奇怪地按时间强制执行值的唯一性,因此您需要做的就是循环直到time 包不再报告当前纳秒的相同值。这不会在 1 纳秒后发生,实际上 UnixNano 在我的机器上的分辨率约为 100 纳秒,并且大约每 0.5 毫秒更新一次。

package main

import (
    "fmt"
    "time"
)

func main() 
    fmt.Println(time.Now().UnixNano())
    smallWait()
    fmt.Println(time.Now().UnixNano())


func smallWait() 
    for start := time.Now().UnixNano(); time.Now().UnixNano() == start; 

循环是不言自明的,只需重复直到UnixNano() 不同

【讨论】:

我正在使用一个我无法控制的包,它以纳秒为单位定义唯一性。可悲的是,我可以并且确实在同一纳秒内调用它两次。所以,我只关心某些包是出于与时间无关的原因。 那么你的问题归结为不等待超过 1 纳秒,而是等到 time 包不再报告它在同一纳秒内的时间,这是不一样的事物。在我的测试中,time.Now().UnixNano() 仅每 0.5 毫秒左右更新一次。唯一能保证做到这一点的方法是只休眠最少的时间,或者运行一个循环并继续检查值是否已经改变。 这是我暂时定下来的。

以上是关于在 Go 中保证至少经过一纳秒的最省时方法是啥? time.Sleep(time.Nanosecond) 可能需要几毫秒的主要内容,如果未能解决你的问题,请参考以下文章

使用 Perl 检查数据数组中重复项的最有效方法是啥?

将视图返回到 ArraySeq 的最佳方法是啥?

在 Laravel 4.2 中保护视图的最有效方法是啥?

检查 SQL Server 中是不是存在触发器的最便携方法是啥?

从应用程序将设备连接到 iPad 的最简单方法是啥?

重写大型 IN 子句的最高效方法是啥?