我一直在测试对一段代码的一些优化(具体来说,elif n in [2,3]
是否比 elif n == 2 或 n == 3 更快
) 并注意到一些奇怪的事情。
使用 timeit.default_timer
我对该函数的每个版本进行了几次运行,第一次运行总是比后续的运行慢得多(值从大约 0.01 秒开始一直拖到约 0.003)。
python 是否在幕后做了一些事情来优化以后运行的代码?这无论如何都不是真正的问题,但我很想知道发生了什么(如果有的话)
最佳答案
在 CPython(引用 Python 实现)上没有这样的通用优化。可能会发生各种更具体的事情,但我们无法确定是什么。
Marcos 的回答表明它是 pyc
文件创建,但这不是 timeit
的工作方式,即使您自己调用 timeit.default_timer
(您不应该 - 您应该使用 timeit.timeit
或 timeit.repeat
或其他此类机制)。
pyc
文件是在导入没有 pyc
文件或其 pyc
文件已过期的模块时创建的。它们不是为 timeit
片段创建的,即使您的计时代码来自导入的模块,典型的 timeit
使用模式也会在计时开始之前导入模块。
您正在调用 timeit.default_timer
而不是让 timeit
按照设计的方式处理事情,但即便如此,任何 pyc
文件创建不太可能在定时代码内发生。
PyPy 是另一种 Python 实现,它使用 JIT 编译,但如果您使用的是 PyPy,您可能会知道。
Numba ,一个用于加速数值计算的库,有自己的 JIT 机制,这也可能导致第一次运行后加速。不注意地依赖 Numba 比不注意地运行 PyPy 更容易。
内存分配在后续运行中可能会发生得更快,这取决于您使用的类型和它们如何与内存管理系统交互的详细信息,以及您的 malloc
的行为方式。例如,在第一次运行后可能会有更多内存块的空闲列表。
还有其他可能性,但最终,我们无法真正判断发生了什么。
关于python - 为什么第一次运行 timeit 通常比后续的慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59457810/