就 Python 的性能而言,列表理解或类似 的函数是否map()比for 循环更快?为什么,从技术上讲,它们 以 C 速度运行* ,而 for 循环以 python 虚拟机速度运行 ?filter()``reduce() ***
map()
filter()``reduce()
假设在我正在开发的游戏中,我需要使用 for 循环绘制复杂而巨大的地图。这个问题肯定是相关的,因为例如,如果列表理解确实更快,那么这将是一个更好的选择,以避免滞后(尽管代码的视觉复杂性)。
以下是粗略的指导方针和基于经验的有根据的猜测。您应该timeit或分析您的具体用例以获得硬数字,这些数字可能偶尔会与以下内容不一致。
timeit
列表推导通常比精确等效的for循环(实际构建列表)快一点,很可能是因为它不必append在每次迭代时查找列表及其方法。但是,列表推导仍然执行字节码级别的循环:
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)通常会稍微快一些。
lambda
map
filter
很有可能,如果这样的代码在用良好的非“优化”Python 编写时还不够快,那么再多的 Python 级别的微优化也无法使其足够快,您应该开始考虑使用 C 语言。微优化通常可以大大加快 Python 代码的速度,对此有一个较低的(绝对值)限制。此外,即使在你达到这个上限之前,咬紧牙关写一些 C 语言也会变得更加经济高效(15% 的加速与 300% 的加速)。