上下文:我正在Python项目中使用ttl实现内存缓存,它必须承受相当大的吞吐量。为了确定缓存记录何时失效,我用时间戳保存它,稍后检索它时,我将这个时间戳与当前时间进行比较。如果差值大于阈值,则该记录过期,应丢弃。
问题:time.time()
或time.perf_counter()
-哪个函数返回其值更快?差别是大还是小?
time.time()
和time.perf_counter()
之间的选择取决于您将在其中使用该函数的上下文。这是因为每个函数处理不同的"时间类型"。
time.time()
处理绝对时间,即"真实世界时间"。(我们习惯的时间类型)。它是从过去的一个固定点测量的。根据文档,time.time()
返回:
(…)以秒为单位的从epoch到浮点数的时间
另一方面,time.perf_counter()
处理的是相对时间,它与现实世界的时间没有明确的关系(即,这种关系对我们来说是未知的,取决于几个因素)。它是使用CPU计数器测量的,并且,正如文档中指定的,应该只用于测量时间间隔:
返回值的参考点没有定义,所以只有连续呼叫结果之间的差异是有效的。
因此,time.perf_counter()
主要用于比较性能。
也就是说,我认为比较这两个函数的速度没有任何意义。它们被设计用于不同的事情—您应该选择最适合您的用例的一个。引用@Martijn Pieters的评论:
有时你需要锤子,有时你需要螺丝刀。你不要问哪个更快;你要么有钉子,要么螺丝。试着用螺丝刀钉钉子可能有用,但不是最好的选择。
从我从你的评论中收集到的,你可能最好使用time.perf_counter()
,因为你的重点是相对时间,而不是"现实世界的时间"。在这种上下文中,time.perf_counter()
可能会更精确,因为它使用:
(…)具有最高可用分辨率的时钟,用于测量短电平持续时间。
我做了一个基准测试来找出
> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 132 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 69.6 nsec per loop
> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 126 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 75.9 nsec per loop
> py -V
Python 3.10.1
我们可以得出结论,time.time()
的速度几乎是time.perf_counter()
的两倍
然而,差异的幅度非常小,约56纳秒
从角度来看,在3ghz cpu上只慢了~168个时钟周期