列表推导式和函数式函数是否比“for 循环"更快? [英] Are list-comprehensions and functional functions faster than "for loops"?

查看:64
本文介绍了列表推导式和函数式函数是否比“for 循环"更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就 Python 的性能而言,是一个列表推导式,或者像 map()filter()reduce() 之类的函数> 比 for 循环更快?为什么,从技术上讲,它们以 C 速度运行,而 for 循环以 Python 虚拟机速度运行?.

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

解决方案

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

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

<预><代码>>>>dis.dis(<`[x for x in range(10)]`的代码对象>)1 0 BUILD_LIST 03 LOAD_FAST 0 (.0)>>6 FOR_ITER 12(到 21)9 STORE_FAST 1 (x)12 LOAD_FAST 1 (x)15 LIST_APPEND 218 JUMP_ABSOLUTE 6>>21 RETURN_VALUE

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

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

<块引用>

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

很有可能,如果用良好的非优化"Python 编写这样的代码还不够快,那么再多的 Python 级别的微优化都不会让它足够快,您应该开始考虑使用 C. 虽然广泛的微优化通常可以显着加快 Python 代码的速度,但对此有一个较低的(绝对值)限制.此外,即使在您达到上限之前,咬紧牙关写一些 C 也变得更具成本效益(15% 的加速比 300% 的加速).

In terms of performance in Python, is a list-comprehension, or functions like map(), filter() and reduce() faster than a for loop? Why, technically, they run in a C speed, while the for loop runs in the python virtual machine speed?.

Suppose that in a game that I'm developing I need to draw complex and huge maps using for loops. This question would be definitely relevant, for if a list-comprehension, for example, is indeed faster, it would be a much better option in order to avoid lags (Despite the visual complexity of the code).

解决方案

The following are rough guidelines and educated guesses based on experience. You should timeit or profile your concrete use case to get hard numbers, and those numbers may occasionally disagree with the below.

A list comprehension is usually a tiny bit faster than the precisely equivalent for loop (that actually builds a list), most likely because it doesn't have to look up the list and its append method on every iteration. However, a list comprehension still does a bytecode-level loop:

>>> 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

Using a list comprehension in place of a loop that doesn't build a list, nonsensically accumulating a list of meaningless values and then throwing the list away, is often slower because of the overhead of creating and extending the list. List comprehensions aren't magic that is inherently faster than a good old loop.

As for functional list processing functions: While these are written in C and probably outperform equivalent functions written in Python, they are not necessarily the fastest option. Some speed up is expected if the function is written in C too. But most cases using a lambda (or other Python function), the overhead of repeatedly setting up Python stack frames etc. eats up any savings. Simply doing the same work in-line, without function calls (e.g. a list comprehension instead of map or filter) is often slightly faster.

Suppose that in a game that I'm developing I need to draw complex and huge maps using for loops. This question would be definitely relevant, for if a list-comprehension, for example, is indeed faster, it would be a much better option in order to avoid lags (Despite the visual complexity of the code).

Chances are, if code like this isn't already fast enough when written in good non-"optimized" Python, no amount of Python level micro optimization is going to make it fast enough and you should start thinking about dropping to C. While extensive micro optimizations can often speed up Python code considerably, there is a low (in absolute terms) limit to this. Moreover, even before you hit that ceiling, it becomes simply more cost efficient (15% speedup vs. 300% speed up with the same effort) to bite the bullet and write some C.

这篇关于列表推导式和函数式函数是否比“for 循环"更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆