Go语言的时间精确度有多高?

huangapple go评论88阅读模式
英文:

How precise is Go's time, really?

问题

Go的time包声称提供纳秒级精度。
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是如何实现纳秒级精度的?

英文:

Go's time package claims giving a nanosecond precision.
http://golang.org/src/pkg/time/time.go

I'm wondering how it is implemented and if I can trust it. My doubts come from Python, which clearly documents its difficulties and limitations with time:

> From http://docs.python.org/2/library/time.html
>
> The precision of the various real-time functions may be less than
> suggested by the units in which their value or argument is expressed.
> E.g. on most Unix systems, the clock “ticks” only 50 or 100 times a
> second.
>
> On the other hand, the precision of time() and sleep() is better than
> their Unix equivalents: times are expressed as floating point numbers,
> time() returns the most accurate time available (using Unix
> gettimeofday() where available), and sleep() will accept a time with a
> nonzero fraction (Unix select() is used to implement this, where
> available).

Since the operating systems are giving such a hard time to python, how does Go achieve its nanosecond precision?

答案1

得分: 37

关于实现部分,time.Now()会回退到在运行时实现的一个函数。你可以查看C时间实现time·now的汇编实现(在这种情况下是linux amd64)。然后它使用clock_gettime,提供纳秒级的分辨率。在Windows上,这是通过调用GetSystemTimeAsFileTime来实现的,它也生成纳秒级(不是很高的分辨率,但是纳秒级)。

所以,是的,分辨率取决于操作系统,你不能期望它在每个操作系统上都是准确的,但开发人员正在努力使其尽可能好。例如,在go1.0.3中,FreeBSD的time·now使用了gettimeofday而不是clock_gettime,后者只提供毫秒级的精度。你可以通过查看存储在AX中的值来看到这一点,因为它是系统调用id。如果你查看引用的汇编代码,你会看到毫秒值被乘以1000以得到纳秒。然而,这个问题现在已经修复了

如果你想确保,可以查看运行时源代码中的相应实现,并查阅操作系统的手册。

英文:

Well as for the implementation, time.Now() falls back to a function implemented in the runtime.
You can review the C time implementation and the implementation for time·now in assembly (linux amd64 in this case). This then uses clock_gettime, which provides nano seconds resolution. On windows, this is realized by calling GetSystemTimeAsFileTime, which too generates nanoseconds (not as high res but nanoseconds).

So yes, the resolution depends on the operating system and you can't expect it to be accurate on every OS but the developers are trying to make it as good as it can be. For example, in go1.0.3, time·now for FreeBSD used gettimeofday instead of clock_gettime, which only offers millisecond precision. You can see this by looking at the value stored in AX, as it is the syscall id. If you take a look at the referenced assembly, you can see that the ms value is mulitplied by 1000 to get the nanoseconds. However, this is fixed now.

If you want to be sure, check the corresponding implementations in the runtime source code and ask the manuals of your operating system.

答案2

得分: 18

Python的time.time函数的一个问题是它返回一个浮点数。浮点数是一个IEEE 754双精度数,具有53位精度。

自从1970-01-01(纪元)以来已经超过2**30秒,因此您需要61(31 + 30)位精度来存储从1970-01-01以来准确到纳秒的时间。

不幸的是,这比Python浮点数可以存储的位数少7或8位,这意味着Python浮点数始终比go时间不精确。

为了量化这一点,下面的演示显示,由于“float”类型的限制,Python时间最多只能精确到100纳秒。

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

因此,go从int64开始,并以nS计数,没有这些限制,并且受底层操作系统的精度限制,nemo解释得非常好。

英文:

One of the problems with Python's time.time function is that it returns a float. A float is an IEEE 754 double-precision number which has 53 bits of precision.

Since it is now more than 2**30 seconds since 1970-01-01 (the epoch) you need 61 (31 + 30) bits of precision to store time accurate to the nanosecond since 1970-01-01.

Unfortunately that is 7 or 8 bits short of what you can store in a python float, meaning that python floats will always be less precise than go time.

To quantify that the demonstration below shows that python time is at most accurate to 100nS just due to the limitations of the float type.

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

So go, starting with an int64 and counting in nS doesn't have these limitations and is limited to the precision of the underlying OS as explained very well by nemo.

答案3

得分: 0

如果您有兴趣查询操作系统以获取clock_gettime返回值的精度,您可以使用适用于您的操作系统的syscall包,调用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,可以获取壁钟时间的精度。

英文:

If you are interested in querying the operating system to get the precision of the values returned by clock_gettime, you can make a syscall to clock_getres using the syscall package appropriate to your operating system. For example, on Unix platforms you can do:

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)
}

Values from the monotonic clock are used by the time package for comparisons and operations involving times; the precision of the wall-clock time is similarly obtained by changing unix.CLOCK_MONOTONIC in the above example to unix.CLOCK_REALTIME.

huangapple
  • 本文由 发表于 2013年1月31日 01:50:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/14610459.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定