Skip to content Skip to sidebar Skip to footer

Does Making Local Aliases Of Variables Speed Up List Comprehensions As It Does Loops?

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)

Solution 1:

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

A typical result of this script was

Not a local variable:
1.22310686111Local variable:
1.17974805832

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

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.

Post a Comment for "Does Making Local Aliases Of Variables Speed Up List Comprehensions As It Does Loops?"