Go 的时间到底有多精确?
Posted
技术标签:
【中文标题】Go 的时间到底有多精确?【英文标题】:How precise is Go's time, really? 【发布时间】:2013-01-30 17:50:11 【问题描述】:Go 的时间包声称可以提供纳秒级的精度。 http://golang.org/src/pkg/time/time.go
我想知道它是如何实现的,我是否可以信任它。我的疑虑来自 Python,它清楚地记录了它的困难和限制:
来自http://docs.python.org/2/library/time.html
各种实时功能的精度可能低于 由表达它们的值或参数的单位建议。 例如。在大多数 Unix 系统上,时钟“滴答”一次只有 50 或 100 次。 第二个。
另一方面,time() 和 sleep() 的精度优于 它们的 Unix 等价物:时间表示为浮点数, time() 返回可用的最准确时间(使用 Unix gettimeofday() (如果可用),并且 sleep() 将接受一个时间 非零分数(Unix select() 用于实现这一点,其中 可用)。
既然操作系统对 python 的要求如此之高,那么 Go 是如何实现其纳秒级精度的呢?
【问题讨论】:
【参考方案1】:关于实现,time.Now()
回退到运行时中实现的函数。
您可以查看C time implementation 和time·now
in assembly 的实现(在本例中为linux amd64)。然后使用clock_gettime
,它提供纳秒分辨率。在 Windows 上,这是通过调用 GetSystemTimeAsFileTime
来实现的,too generates nanoseconds(不是高分辨率,而是纳秒)。
所以是的,分辨率取决于操作系统,您不能指望它在每个操作系统上都是准确的,但开发人员正在努力使其尽可能好。例如,在 go1.0.3 中,time·now
用于 FreeBSD used gettimeofday
而不是 clock_gettime
,后者仅提供毫秒精度。您可以通过查看存储在AX
中的值来了解这一点,因为它是syscall id。如果您查看引用的程序集,您可以看到 ms 值乘以 1000 以获得纳秒。但是,这是固定的now。
如果您想确定,请查看运行时源代码中的相应实现,并询问您的操作系统的手册。
【讨论】:
support.microsoft.com/en-us/help/188768/… 此文档表明 GetSystemTimeAsFileTime 以 100 纳秒的间隔工作,而不是纳秒 @GeorgePolevoy 当然底层单位仍然是纳秒。时钟使用 100 ns 的分辨率,因此它以 100ns 的步长递增,这使您能够以纳秒为单位进行计数,尽管不如单个纳秒那么精确。正如我在答案中所说的那样。【参考方案2】:Python 的time.time 函数的一个问题是它返回一个float。浮点数是 IEEE 754 double-precision number,精度为 53 位。
由于距 1970-01-01(纪元)现在已超过 2**30 秒,因此您需要 61 (31 + 30) 位精度来存储自 1970-01-01 以来精确到纳秒的时间。
不幸的是,这比您可以存储在 python 浮点数中的内容少 7 或 8 位,这意味着 python 浮点数总是不如 go time 精确。
为了量化,下面的演示表明python时间最多精确到100nS,只是由于float
类型的限制。
>>> t = time()
>>> t
1359587524.591781
>>> t == t + 1E-6
False
>>> t == t + 1E-7
True
所以,从int64
开始并以 nS 为单位进行计数没有这些限制,并且仅限于底层操作系统的精度,正如 nemo 很好地解释的那样。
【讨论】:
【参考方案3】:如果您有兴趣查询操作系统以获得clock_gettime
返回的值的精度,您可以使用适合您操作系统的系统调用包对clock_getres
进行系统调用。例如,在 Unix 平台上,您可以这样做:
package main
import (
"fmt"
"golang.org/x/sys/unix"
)
func main()
res := unix.Timespec
unix.ClockGetres(unix.CLOCK_MONOTONIC, &res)
fmt.Printf("Monotonic clock resolution is %d nanoseconds\n", res.Nsec)
时间包使用来自单调时钟的值进行比较和涉及时间的操作;通过将上例中的unix.CLOCK_MONOTONIC
更改为unix.CLOCK_REALTIME
,类似地获得挂钟时间的精度。
【讨论】:
以上是关于Go 的时间到底有多精确?的主要内容,如果未能解决你的问题,请参考以下文章
模拟面试23届本科生拿下字节/京东/网易研发offer,到底有多强?
模拟面试23届本科生拿下字节/京东/网易研发offer,到底有多强?