Go的时间有多精确,真的吗?

时间:2013-01-30 17:50:11

标签: time go

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如何实现其纳秒精度?

3 个答案:

答案 0 :(得分:33)

对于实现,time.Now()回退到运行时中实现的函数。 您可以查看C time implementationtime·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

如果您想确定,请检查运行时源代码中的相应实现,并询问操作系统的手册。

答案 1 :(得分:14)

Python time.time函数的一个问题是它返回float。 float是IEEE 754 double-precision number,其精度为53位。

由于自1970-01-01(纪元)以来现在超过2 ** 30秒,因此需要61(31 + 30)位精度来存储自1970-01-01以来精确到纳秒的时间。 / p>

不幸的是,这比你在python float中存储的内容短7或8位,这意味着python float总是不如go time精确。

量化下面的演示表明,由于float类型的限制,python时间最多精确到100nS。

>>> t = time()
>>> t
1359587524.591781
>>> t == t + 1E-6
False
>>> t == t + 1E-7
True

所以,从int64开始,并且在nS中计数没有这些限制,并且仅限于底层操作系统的精度,正如nemo所解释的那样。

答案 2 :(得分:0)

如果您有兴趣查询操作系统以获取clock_gettime返回值的精度,则可以使用适合您操作系统的syscall软件包对clock_getres进行syscall。例如,在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,可以得到时钟时间的精度。