Python 中单个方法的性能测量技术之间的差异

Differences between performance measurement techniques for a single method in Python

我想弄清楚我的 LDA classifier 预测单个 1080 维向量的 class 需要多长时间。我阅读了这些主题:

发现有几种方法可以做到这一点。我测试了其中的几个,但它们产生了截然不同的结果。

time module:

import time
start = time.time()
lda.predict(sample)
end = time.time()
print(str((end-start)*10**6), 'µs')
>>> 1452.9228210449219 µs

timeit module's default_timer:

from timeit import default_timer as timer
start = timer()
lda.predict(sample)
end = timer()
print(str((end-start)*10**6), 'µs')
>>> 979.6129997994285 µs

iPython %timeit 魔法函数:

%timeit lda.predict(sample)
>>> 52 µs ± 873 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

我是在做一些荒谬的事情还是对这些差异有其他解释?信任哪一个?先感谢您。

首先,您的系统中可能有多个时钟,具有不同的分辨率和精度。所以,一个时钟可能真的很准确(给我 deez 纳秒,m8!),而另一个可能只测量一整天的时间。可能有 none 实际上在做后者,但你明白了。我还发现了一个非常有趣的 website,它解释了计算机如何测量时间。

其次,CPU 并不总是 以同样的速度完成您的任务,因为它还有很多其他事情要做!它实际上以惊人的速度不断地在大量不同的任务之间切换,对于我们这些行动迟缓的人类来说,它看起来像是同时完成所有这些任务。嗯,不。因此,现在您的 CPU 可能比之前几毫秒更忙,这意味着您的任务可能会在几毫秒后执行,反之亦然。

至于iPython的%timeit code,它不像你用的其他方法,运行s code 多次,因此,虽然第一个 运行 可能会花费很多时间,但由于 缓存 ,后续 运行 可能会快得多。因此,在这种情况下,在第一个 运行 期间实际计算结果(这很慢)然后转储到内存中,而其他 69999 运行 只是获取该结果,这恰好更快比做计算。我不认为您可以轻松禁用缓存,因为缓存确实内置于 CPU 中,因此 任何 重复作业的结果可能会被缓存。


但后者可能并非如此。事实证明 %timeit 使用 timeit.Timer(第 139 行的定义 of iPython's source code 和第 945 行的用法)* 在测量时间之前禁用垃圾收集。这很可能是加速如此剧烈的原因,因为垃圾收集需要花费大量时间,并且如果您的代码相当复杂,那么 GC 必然有很多工作要做。


* 是的,我知道您可以直接链接到某些行,但出于某种原因这对我不起作用,对此感到抱歉。