I have been operating under the theory that generator expressions tend to be more efficient than normal loops. But then I ran into the following example: write a function which given a number, N
, and some factors, ps
, returns the sum of all the numbers under N
that are a multiple of at least one factor.
Here is a loop version and a shorter generator expression version:
def loops(N, ps):
total_sum = 0
for i in xrange(N):
for p in ps:
if i%p == 0:
total_sum += i
break
return total_sum
def genexp(N, ps):
return sum(i for i in xrange(N)
if any(i%p == 0 for p in ps))
I'd expect the two to perform roughly equal, with maybe the comprehension version a little faster, but what I didn't expect was this:
for func in ('loops', 'genexp'):
print func, timeit.timeit('%s(100000, [3,5,7])' % func,
number=100,
setup='from __main__ import %s' % func)
loops 2.82878184319
genexp 10.1663100719
4x slower isn't even close! Why? What am I misunderstanding?