循环时,对变量进行局部别名是否会加快列表的理解速度? [英] Does making local aliases of variables speed up list comprehensions as it does loops?
问题描述
在Python中,名称查找相对昂贵,因此对于大型循环,您可以通过更改类似内容来获得性能优势
Name lookups are relatively expensive in Python, so for large loops you can get a performance advantage by changing something like
for element in my_list:
do_something(element)
类似
ds = do_something
for element in my_list:
ds(element)
,以便解释器仅需在每次迭代中查找局部变量.如果该函数由列表推导调用,此优化是否也有用?
so that the interpreter only has to look up a local variable on each iteration. Is this optimization also useful if the function is being invoked by a list comprehension?
推荐答案
是.我使用timeit
设置了一个简单示例:
Yes. I set up a simple example using timeit
:
from __future__ import print_function
import timeit
setup = '''
def return_five():
return 6
def f1():
return [return_five() for i in range(10000)]
def f2():
r = return_five
return [r() for i in range(10000)]
'''
print('Not a local variable:')
print(min(timeit.Timer('a = f1()', setup=setup).repeat(7, 1000)))
print('Local variable:')
print(min(timeit.Timer('a = f2()', setup=setup).repeat(7, 1000)))
此脚本的典型结果是
Not a local variable:
1.22310686111
Local variable:
1.17974805832
我惊讶地发现第二个功能f2
始终比第一个功能快3.5%.我曾期望Python在遇到f1
中的列表理解时只会查找return_five
一次,但似乎每次都查找一次.
I was surprised to see that the second function, f2
, was consistently about 3.5% faster than the first function. I was expecting that Python would only look up return_five
once when it encountered the list comprehension in f1
, but it seems to look it up each time.
(大概是这样,如果所涉及的函数之一具有以某种方式更改名称查找的副作用,那么列表理解就可以正确执行.这对我来说似乎是一个相当病理的副作用,但我想最好还是稍加修改比引入可能导致难以跟踪的错误的优化效率低).
(Presumably this is so that the list comprehension behaves correctly if one of the functions involved has the side effect of changing the name lookup somehow. That seems like a pretty pathological side effect to me, but I guess it’s better to be slightly inefficient than to introduce an optimization that could cause hard-to-track-down bugs.)
当我将列表理解的大小从10,000更改为10时,差距缩小了,因此f2
仅比f1
快0.8%.这确认了在通过循环的每次迭代中都在执行函数名称查找.
When I changed the size of the list comprehensions from 10,000 to 10, the gap closed so that f2
was only 0.8% faster than f1
. This confirms that the function name lookup is being performed on each iteration through the loop.
这篇关于循环时,对变量进行局部别名是否会加快列表的理解速度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!