小编典典

列表理解和功能函数是否比“for 循环”更快?

all

就 Python 的性能而言,列表理解或类似 的函数是否map()比for 循环更快?为什么,从技术上讲,它们 以 C 速度运行* ,而
for 循环以 python 虚拟机速度运行filter()``reduce()
***

假设在我正在开发的游戏中,我需要使用 for
循环绘制复杂而巨大的地图。这个问题肯定是相关的,因为例如,如果列表理解确实更快,那么这将是一个更好的选择,以避免滞后(尽管代码的视觉复杂性)。


阅读 60

收藏
2022-06-23

共1个答案

小编典典

以下是粗略的指导方针和基于经验的有根据的猜测。您应该timeit或分析您的具体用例以获得硬数字,这些数字可能偶尔会与以下内容不一致。

列表推导通常比精确等效的for循环(实际构建列表)快一点,很可能是因为它不必append在每次迭代时查找列表及其方法。但是,列表推导仍然执行字节码级别的循环:

>>> dis.dis(<the code object for `[x for x in range(10)]`>)
 1           0 BUILD_LIST               0
             3 LOAD_FAST                0 (.0)
       >>    6 FOR_ITER                12 (to 21)
             9 STORE_FAST               1 (x)
            12 LOAD_FAST                1 (x)
            15 LIST_APPEND              2
            18 JUMP_ABSOLUTE            6
       >>   21 RETURN_VALUE

使用列表推导代替 构建列表的循环,毫无意义地累积无意义值的列表然后丢弃列表,由于创建和扩展列表的开销,通常会 更慢。
列表推导并不是天生就比一个好的旧循环更快的魔法。

至于功能列表处理函数:虽然这些是用 C 编写的,并且可能优于用 Python 编写的等效函数,但它们 不一定 是最快的选择。 如果 该函数也是用
C 编写的,则预计会有所加快。但是大多数情况下使用一个lambda(或其他 Python 函数),重复设置 Python
堆栈帧等的开销会消耗掉任何节省。简单地在线执行相同的工作,没有函数调用(例如列表理解而不是mapor filter)通常会稍微快一些。

假设在我正在开发的游戏中,我需要使用 for
循环绘制复杂而巨大的地图。这个问题肯定是相关的,因为例如,如果列表理解确实更快,那么这将是一个更好的选择,以避免滞后(尽管代码的视觉复杂性)。

很有可能,如果这样的代码在用良好的非“优化”Python 编写时还不够快,那么再多的 Python 级别的微优化也无法使其足够快,您应该开始考虑使用 C
语言。微优化通常可以大大加快 Python 代码的速度,对此有一个较低的(绝对值)限制。此外,即使在你达到这个上限之前,咬紧牙关写一些 C
语言也会变得更加经济高效(15% 的加速与 300% 的加速)。

2022-06-23