Python looping for n times

A Twitter friend proposed an idiom for doing something N times in Python I hadn’t seen before, Using itertools.repeat instead of range. I was curious if it was better.

$ python3 -V
Python 3.4.3
$ python2 -V
Python 2.7.10

$ python3 -m timeit 'for _ in range(10000): pass'
1000 loops, best of 3: 275 usec per loop
$ python3 -m timeit 'for _ in itertools.repeat(None, 10000): pass'
10000 loops, best of 3: 133 usec per loop
$ python3 -m timeit 'for _ in itertools.repeat(1, 10000): pass'
10000 loops, best of 3: 130 usec per loop

$ python2 -m timeit 'for _ in range(10000): pass'
1000 loops, best of 3: 218 usec per loop
$ python2 -m timeit 'for _ in xrange(10000): pass'
1000 loops, best of 3: 179 usec per loop
$ python2 -m timeit 'for _ in itertools.repeat(None, 10000): pass'
10000 loops, best of 3: 122 usec per loop

So huh, itertools.repeat is about 50% the cost of using range. We’re only talking 13ns per iteration, or roughly 50 CPU cycles. If you’re doing meaningful work in that loop it won’t matter. Still it’s neat that itertools.repeat is more efficient. Perhaps this shouldn’t surprise me, it doesn’t have to do the work of generating increasing integers. But I’d assumed no one had optimized itertools this carefully.

Note that in Python3 range is an actual type and doesn’t create a list, tuple, iterator, or generator. Also interesting that repeating an integer is 3% more efficient than repeating None; that’s a reproducible result.

Python2 is faster across the board. I see that a lot in Python and it makes me wonder. But the itertools vs. range/xrange difference is still about 50%, or meaningful.

Having now understood all this I’ll go right back to using range() like my grandpappy did.

One thought on “Python looping for n times

  1. It’s striking how often one bumps into counterintuitive or somewhat unobvious performance weirdness in python, although it hardly ever matters. Although a more current python runtime, unburdened by backwards compatibility runs this sort of thing the way you’d think it should run.

    (because it’s hard to resist pointless nerdoutery)

Comments are closed.