For loops, NumPy and Python optimization

Posted on Updated on

For numerical computations the book Python scripting for computational science recommends avoiding explicit loops and use vectorized NumPy expressions instead. The author Hans Petter Langtangen writes that “a speed-up factor of 10 is often gained” (page 427). The same kind of recommendation is also often give for Matlab programs.

With the timeit module short statements or expressions can be measured. The module runs a piece of code a large number of times. With that module we can measure the speed of a classic for loop, a “list comprehension” for loop and a map implementation of the same small list/array computation:

import timeit
timeit.Timer("""
x2 = [];
for x in range(10):
x2.append(x**2)
""").timeit()

timeit.Timer("""
x2 = [ x**2 for x in range(10) ]
""").timeit()

timeit.Timer("""
x2 = map(lambda x: x**2, range(10))
""").timeit()

On my 2’500 DKK Intel Atom N450 netbook the results are 13.4, 8.7 and 16.6, while our department CIMBI server reports 4.1, 2.8 and 4.5. The middle one has no function evaluations, while the two others have either a ‘append’ or a ‘lambda’ function evaluation. That might be the reason why the middle one is faster.

On small lists it seems not to be an advantage to use NumPy:

timeit.Timer("""
from numpy import asarray
x2 = list(asarray(range(10))**2)
""").timeit()

Here the result is 23.6 on the CIMBI server. That code can be optimized a bit:

timeit.Timer("""
x2 = arange(10)**2
""", setup="from numpy import arange").timeit()

It now reports 4.2, — still not quite as good as the list comprehension version. But if we increase the size of the array NumPy is far superior:

timeit.Timer("""
x2 = [ x**2 for x in range(1000) ]
""").timeit(number=100000)

timeit.Timer("""
x2 = arange(1000)**2
""", setup="from numpy import arange").timeit(number=100000)

Here the CIMBI server reports 22.6 and 0.7 in NumPy’s favor.

(correction 13 december 2010)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s