[Python-Dev] On the possibility of "optimizing" range() calls in for-loops

Alex Martelli aleaxit@yahoo.com
Sat, 14 Jun 2003 11:10:20 +0200


On Saturday 14 June 2003 06:09 am, Chad Netzer wrote:
> I've been thinking about the possibility of an optimization of range()
> calls in for-loops, replacing the list generation with a lazy range
> object.
>
> xrange(), in Python 2.3, now has an iterator, so it should be faster
> than range() in for-loops, which is an incentive to use it more.

Measuring is better than wondering:

with Python's current CVS:

[alex@lancelot Lib]$ python -O timeit.py 'for x in range(2000): pass'
1000 loops, best of 3: 257 usec per loop
[alex@lancelot Lib]$ python -O timeit.py 'for x in xrange(2000): pass'
1000 loops, best of 3: 220 usec per loop


with 2.2.2:

[alex@lancelot Lib]$ python2.2 -O timeit.py 'for x in range(2000): pass'
1000 loops, best of 3: 315 usec per loop
[alex@lancelot Lib]$ python2.2 -O timeit.py 'for x in xrange(2000): pass'
1000 loops, best of 3: 440 usec per loop

So, yes: xrange has accelerated SO much (by a factor of 2) as to
become measurably faster than range (by a little, about 15%) for
this specific usage, while it used to be substantially slower.

However, these days, if you're really in a hurry to repeat some action
2000 times (and don't need the iteration index, which is a reasonably
frequent case), there IS an alternative...:

alex@lancelot Lib]$ python -O timeit.py -s'import itertools' 'for x in 
itertools.repeat(None,2000): pass'
10000 loops, best of 3: 184 usec per loop
[alex@lancelot Lib]$ python -O timeit.py -s'import itertools' 'for x in 
itertools.repeat(None,2000): pass'
1000 loops, best of 3: 183 usec per loop

As you see, this is as much faster than xrange, as xrange is faster
than range.


Alex