I was doing a Python exercise to find all of the even numbers between two values. I came up with the following result
','.join(str(i) for i in range(1000, 3000+1) if i % 2 == 0)
But then I noticed it was a bit slower than using a map
In [105]: %timeit ','.join(str(i) for i in range(1000, 3000+1) if i % 2 == 0)
1000 loops, best of 3: 412 µs per loop
In [107]: %timeit ','.join(map(str, (i for i in range(1000, 3000+1) if i % 2 == 0)))
1000 loops, best of 3: 374 µs per loop
Researching this, I came across this answer which explains that when using a generator expression in a join
The conversion of the generator expression to a list means that the usual benefits of generators (a smaller memory footprint and the potential for short-circuiting) don't apply to str.join, and so the (small) additional overhead that the generator has makes its performance worse.
This would suggest to me that casting a map
to a list
is faster than casting a generator
In [109]: %timeit list(map(str, (i for i in range(1000, 3000+1) if i % 2 == 0)))
1000 loops, best of 3: 366 µs per loop
In [110]: %timeit list(str(i) for i in range(1000, 3000+1) if i % 2 == 0)
1000 loops, best of 3: 399 µs per loop
Why is this the case?