有没有一种比Python默认的一秒更精确的高精度时间测量方式?我怀疑没有跨平台的方法可以做到这一点;我对Unix上的高精度时间感兴趣,特别是在Sun SPARC机器上运行的Solaris。
timeit似乎能够进行高精度时间测量,但我想直接访问时间值而不是测量代码片段所需的时间。
标准的time.time()
函数提供亚秒精度,但此精度因平台而异。对于Linux和Mac平台,精度为+-
1微秒或0.001毫秒。由于时钟实现问题和处理中断,Python在Windows上使用+-
16毫秒的精度。如果您要测量执行时间,则timeit
模块可以提供更高的分辨率。
>>> import time
>>> time.time() #return seconds from epoch
1261367718.971009
Python 3.7引入了新的函数到time
模块,提供了更高的分辨率:
>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289
David的帖子试图展示Windows的时钟分辨率。我对他的输出感到困惑,因此我编写了一些代码,显示我的Windows 8 x64笔记本上的time.time()
分辨率为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
这将输出:
(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)
一种计算 delta 的 1000 次采样平均值的方法:
reduce( lambda a,b:a+b, [measure()[2] for i in range(1000)], 0.0) / 1000.0
连续运行两次会输出什么:
0.001
0.0010009999275207519
在我的Windows 8 x64上,time.time()
函数的精度为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
返回:
4.3571334791658954e-07
这是 ~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
(这可能会在一段时间后漂移,但您可以偶尔进行更正,例如dc > 3600
每小时将其更正一次)
time.clock
函数可高精度地测量经过的时间; 在OS X和Linux上,它测量CPU时间。Python 3.3版本之后,建议使用perf_counter
函数来测量经过的时间,使用process_time
函数来测量CPU时间,time.clock
已经被弃用。 - GeorgePython会尽力使用最精确的时间函数来实现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 */
}
}
(来自http://svn.python.org/view/python/trunk/Modules/timemodule.c?revision=81756&view=markup)
这是一个链接,指向Python官方网站上的timemodule.c文件。如果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())
它的输出为:
0.03125
0.03125
2.560001310720671e-07
1.0005455362793145
import time
t_ = time.clock()
#Your code here
print 'Time in function', time.clock() - t_
编辑:糟糕,我没有看清问题,您想要知道确切的时间,而不是花费的时间...
Python 3.7引入了6个新的时间函数,具有纳秒分辨率,例如,您可以使用time.time_ns()
而不是time.time()
来避免浮点数精度问题:
import time
print(time.time())
# 1522915698.3436284
print(time.time_ns())
# 1522915698343660458
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类型的纳秒数。
time.clock()
函数有13位小数,但在Linux上只有2位。
time.time()
在Linux上有17位小数,在Windows上有16位小数,但实际精度不同。time.clock()
来进行基准测试的说法。它的精确度不够,所以要使用哪个计时器取决于操作系统。time.time()
的时间分辨率很高:>>> time.time(), time.time()
(1281384913.4374139, 1281384913.4374161)
然而,在 Windows 上,time 函数似乎使用最后一次调用的数字:
>>> time.time()-int(time.time()), time.time()-int(time.time()), time.time()-time.time()
(0.9570000171661377, 0.9570000171661377, 0.0)
import platform, platform.system()
),以确定是使用time.clock()
还是time.time()
。import time
# 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 t1-t0
samples = [measure() for i in range(30)]
for s in samples:
print(f'time delta: {s:.4f} seconds')
这些结果是在运行Python 3.7 64位的Windows 10 Pro 64位系统上收集的。
这篇评论,由tiho于2014年3月27日17:21留下,值得成为一篇独立的回答:
为了避免平台特定代码,请使用timeit.default_timer()。
time.clock
自3.3版本起已被弃用。 - Szabolcs Dombi
time.perf_counter
)和PEP-564提供了关于各种操作系统上计时性能的丰富信息,包括分辨率等表格。 - djvg