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如何实现其纳秒精度?
答案 0 :(得分:33)
对于实现,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。
如果您想确定,请检查运行时源代码中的相应实现,并询问操作系统的手册。
答案 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
,可以得到时钟时间的精度。