Python中的高精度时钟

fua*_*uad 45 python time

有没有办法在Python中以高精度测量时间---比一秒更精确?我怀疑是否有跨平台的方式来做到这一点; 我对Unix上的高精度时间感兴趣,特别是在Sun SPARC机器上运行的Solaris.

timeit似乎能够进行高精度的时间测量,但我不想测量代码片段需要多长时间,而是想直接访问时间值.

daf*_*daf 54

标准time.time()函数提供亚秒级精度,但精度因平台而异.对于Linux和Mac,精度为+-1微秒或0.001毫秒.+-由于进程中断导致时钟实现问题,Windows上的Python使用16毫秒的精度.timeit如果您正在测量执行时间,模块可以提供更高的分辨率.

>>> import time
>>> time.time()        #return seconds from epoch
1261367718.971009      
Run Code Online (Sandbox Code Playgroud)

Python 3.7为time模块引入了新功能,提供更高的分辨率:

>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在Windows上,time.time()的精度约为16毫秒. (32认同)
  • 在 python >=3.3 中,答案是 [time.perf_counter()](https://docs.python.org/3.5/library/time.html#time.perf_counter) 和 time.process_time() (10认同)
  • @Jcyrss,“time_ns”不提供纳秒分辨率,它只是返回以纳秒为单位的时间。这可能会也可能不会提高分辨率。Linux 和 Windows 的测量时钟分辨率记录在 [PEP 564](https://www.python.org/dev/peps/pep-0564/#annex-clocks-resolution-in-python) 中。对于 Windows,测量的“time_ns”分辨率为 **318 us**。 (7认同)
  • 在Windows上不准确(没用) (2认同)
  • time_ns 确实提供纳秒分辨率。但它在 Windows 上真的精确吗?官方文档里好像没有说明 (2认同)

Joe*_*erg 23

Python努力使用最精确的时间函数来实现您的平台time.time():

/* Implement floattime() for various platforms */

static double
floattime(void)
{
    /* There are three ways to get the time:
      (1) gettimeofday() -- resolution in microseconds
      (2) ftime() -- resolution in milliseconds
      (3) time() -- resolution in seconds
      In all cases the return value is a float in seconds.
      Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
      fail, so we fall back on ftime() or time().
      Note: clock resolution does not imply clock accuracy! */
#ifdef HAVE_GETTIMEOFDAY
    {
        struct timeval t;
#ifdef GETTIMEOFDAY_NO_TZ
        if (gettimeofday(&t) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#else /* !GETTIMEOFDAY_NO_TZ */
        if (gettimeofday(&t, (struct timezone *)NULL) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
    }

#endif /* !HAVE_GETTIMEOFDAY */
    {
#if defined(HAVE_FTIME)
        struct timeb t;
        ftime(&t);
        return (double)t.time + (double)t.millitm * (double)0.001;
#else /* !HAVE_FTIME */
        time_t secs;
        time(&secs);
        return (double)secs;
#endif /* !HAVE_FTIME */
    }
}
Run Code Online (Sandbox Code Playgroud)

(来自http://svn.python.org/view/python/trunk/Modules/timemodule.c?revision=81756&view=markup)


cod*_*k3y 20

大卫的帖子试图显示Windows上的时钟分辨率.我对他的输出感到困惑,所以我写了一些代码,表明time.time()我的Windows 8 x64笔记本电脑的分辨率为1毫秒:

# measure the smallest time delta by spinning until the time changes
def measure():
    t0 = time.time()
    t1 = t0
    while t1 == t0:
        t1 = time.time()
    return (t0, t1, t1-t0)

samples = [measure() for i in range(10)]

for s in samples:
    print s
Run Code Online (Sandbox Code Playgroud)

哪个输出:

(1390455900.085, 1390455900.086, 0.0009999275207519531)
(1390455900.086, 1390455900.087, 0.0009999275207519531)
(1390455900.087, 1390455900.088, 0.0010001659393310547)
(1390455900.088, 1390455900.089, 0.0009999275207519531)
(1390455900.089, 1390455900.09, 0.0009999275207519531)
(1390455900.09, 1390455900.091, 0.0010001659393310547)
(1390455900.091, 1390455900.092, 0.0009999275207519531)
(1390455900.092, 1390455900.093, 0.0009999275207519531)
(1390455900.093, 1390455900.094, 0.0010001659393310547)
(1390455900.094, 1390455900.095, 0.0009999275207519531)
Run Code Online (Sandbox Code Playgroud)

并且可以对delta进行1000个样本平均值:

reduce( lambda a,b:a+b, [measure()[2] for i in range(1000)], 0.0) / 1000.0
Run Code Online (Sandbox Code Playgroud)

两次连续运行的输出:

0.001
0.0010009999275207519
Run Code Online (Sandbox Code Playgroud)

所以time.time()我的Windows 8 x64的分辨率为1毫秒.

类似的运行time.clock()返回0.4微秒的分辨率:

def measure_clock():
    t0 = time.clock()
    t1 = time.clock()
    while t1 == t0:
        t1 = time.clock()
    return (t0, t1, t1-t0)

reduce( lambda a,b:a+b, [measure_clock()[2] for i in range(1000000)] )/1000000.0
Run Code Online (Sandbox Code Playgroud)

返回:

4.3571334791658954e-07
Run Code Online (Sandbox Code Playgroud)

这是〜0.4e-06

一个有趣的事情time.clock()是,它返回自首次调用方法以来的时间,因此如果您想要微秒分辨率的挂起时间,您可以执行以下操作:

class HighPrecisionWallTime():
    def __init__(self,):
        self._wall_time_0 = time.time()
        self._clock_0 = time.clock()

    def sample(self,):
        dc = time.clock()-self._clock_0
        return self._wall_time_0 + dc
Run Code Online (Sandbox Code Playgroud)

(这可能会在一段时间后漂移,但你可以偶尔纠正,例如dc > 3600每小时纠正一次)

  • 在Windows上,`time.clock`测量经过的时间到高精度.在OS X和Linux上,它测量CPU时间.从Python 3.3开始,[不推荐](https://docs.python.org/3/library/time.html#time.process_time)支持`perf_counter`来测量经过的时间,而`process_time`来测量CPU. (3认同)
  • 这个答案具有误导性。仅仅因为您的 Windows 在运行此脚本时将计时器分辨率设置为 1 毫秒,并不能保证其他进程不能或不会将其设置为更高分辨率。默认分辨率为 15.6 毫秒,任何进程都可以更改该值。我运行了你的脚本,得到了 15 毫秒的增量,然后我使用 https://github.com/tebjan/TimerTool 并将其设置为 1 毫秒,再次运行它并得到了 1 毫秒的时间增量。小心假设 Windows 保持 1 毫秒计时器分辨率,您应该明确并在需要时在脚本开头自行设置它。 (3认同)

Khe*_*ben 14

你也可以使用time.clock()它计算Unix上进程使用的时间和自Windows上第一次调用它以来的时间.它比time.time()更精确.

它是衡量性能的常用功能.

打电话吧

import time
t_ = time.clock()
#Your code here
print 'Time in function', time.clock() - t_
Run Code Online (Sandbox Code Playgroud)

编辑:Ups,我想念你的问题,因为你想知道确切的时间,而不是花费的时间......


ere*_*eOn 8

如果Python 3是一个选项,您有两个选择:

  • time.perf_counter它总是在您的平台上使用最准确的时钟.它确实包括在流程之外花费的时间.
  • time.process_time返回CPU时间.它包括在流程之外花费的时间.

两者之间的差异可以显示为:

from time import (
    process_time,
    perf_counter,
    sleep,
)

print(process_time())
sleep(1)
print(process_time())

print(perf_counter())
sleep(1)
print(perf_counter())
Run Code Online (Sandbox Code Playgroud)

哪个输出:

0.03125
0.03125
2.560001310720671e-07
1.0005455362793145
Run Code Online (Sandbox Code Playgroud)


小智 5

time.clock()在 Windows 上有 13 位小数,但在 Linux 上只有 2 位。 time.time()Linux 上有 17 位小数,Windows 上有 16 位小数,但实际精度不同。

time.clock()我不同意应该用于 Unix/Linux 基准测试的文档。它不够精确,所以使用什么定时器取决于操作系统。

在 Linux 上,时间分辨率较高time.time()

>>> time.time(), time.time()
(1281384913.4374139, 1281384913.4374161)
Run Code Online (Sandbox Code Playgroud)

然而,在 Windows 上,时间函数似乎使用最后调用的号码:

>>> time.time()-int(time.time()), time.time()-int(time.time()), time.time()-time.time()
(0.9570000171661377, 0.9570000171661377, 0.0)
Run Code Online (Sandbox Code Playgroud)

即使我在 Windows 中的不同行上编写调用,它仍然返回相同的值,因此实际精度较低。

因此,在严格的测量中,必须进行平台检查 ( import platform, platform.system()) 以确定是否使用time.clock()time.time()

(在 Windows 7 和 Ubuntu 9.10 上使用 python 2.6 和 3.1 进行测试)

  • 当然,这并不是因为它返回最后一个值,而是因为您在比时钟分辨率更短的时间内进行了多次调用。 (7认同)
  • 为了避免特定于平台的代码,请使用 timeit.default_timer() (5认同)

Chr*_*nds 5

Python 3.7引入了6个具有纳秒分辨率的新时间函数,例如,time.time()可以代替使用time.time_ns()

import time
print(time.time())
# 1522915698.3436284
print(time.time_ns())
# 1522915698343660458
Run Code Online (Sandbox Code Playgroud)

这6个功能在PEP 564中进行了描述:

time.clock_gettime_ns(clock_id)

time.clock_settime_ns(clock_id, time:int)

time.monotonic_ns()

time.perf_counter_ns()

time.process_time_ns()

time.time_ns()

这些函数类似于不带_ns后缀的版本,但是作为Python int返回几纳秒。

  • 这些函数与原始函数一样准确(或不准确)。唯一改变的是返回数据的“格式”:它们不再是浮点数,而是整数。例如,1ms 返回 1000000,而不是 0.001。 (2认同)

归档时间:

查看次数:

82995 次

最近记录:

6 年,5 月 前