I am looking in to the performance issues of the loop like structures in Python and found the following statements:
Besides the syntactic benefit of list comprehensions, they are often as fast or faster than equivalent use of map. (Performance Tips)
List comprehensions run a bit faster than equivalent for-loops (unless you're just going to throw away the result). (Python Speed)
I am wondering what difference under the hood gives list comprehension this advantage. Thanks.
Test one: throwing away the result.
Here's our dummy function:
And here are our challengers:
I won't do an analysis of its raw speed, only why, per the OP's question. Lets take a look at the diffs of the machine code.
The race is on. Listcomp's first move is to build an empty list, while for loop's is to setup a loop. Both of them then proceed to load global range(), the constant 100, and call the range function for a generator. Then they both get the current iterator and get the next item, and store it into the variable i. Then they load examplefunc and i and call examplefunc. Listcomp appends it to the list and starts the loop over again. For loop does the same in three instructions instead of two. Then they both load None and return it.
So who seems better in this analysis? Here, list comprehension does some redundant operations such as building the list and appending to it, if you don't care about the result. For loop is pretty efficient too.
If you time them, using a for loop is about one-third faster than a list comprehension. (In this test, examplefunc divided its argument by five and threw it away instead of doing nothing at all.)
Test two: Keeping the result like normal.
No dummy function this test. So here are our challengers:
The diff isn't any use to us today. It's just the two machine codes in two blocks.
List comp's machine code:
For loop's machine code:
As you can probably already tell, the list comprehension has fewer instructions than for loop does.
List comprehension's checklist:
range
.100
.range
.i
.i
.l
to the anonymous empty list.For loop's checklist:
l
to the anonymous empty list.range
.100
.range
.i
.l
.append
on that list.i
.append
.(Not including these steps: Load
None
, return it.)The list comprehension doesn't have to do these things:
i
twice per loopIn conclusion, listcomp is a lot faster if you are going to use the values, but if you don't it's pretty slow.
Real speeds
Test one: for loop is faster by about one-third*
Test two: list comprehension is faster by about two-thirds*
*About -> second decimal place acurrate