[issue32945] sorted(generator) is slower than sorted(list-comprehension)
Raymond Hettinger
report at bugs.python.org
Sun Feb 25 16:28:09 EST 2018
Raymond Hettinger <raymond.hettinger at gmail.com> added the comment:
FYI, here is the disassembly of the inner code objects. It shows where the difference in speed arises:
>>> from dis import dis
>>> def f():
lc = [i for i in [1, 2]]
ge = (i for i in [1, 2])
return lc, ge
>>> for obj in f.__code__.co_consts:
if type(obj) == type(f.__code__):
print(obj)
dis(obj)
<code object <listcomp> at 0x113d881e0, file "<pyshell#26>", line 2>
2 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 8 (to 14)
6 STORE_FAST 1 (i)
8 LOAD_FAST 1 (i)
10 LIST_APPEND 2 <-- Append directly
12 JUMP_ABSOLUTE 4
>> 14 RETURN_VALUE
<code object <genexpr> at 0x1035afe40, file "<pyshell#26>", line 3>
3 0 LOAD_FAST 0 (.0)
>> 2 FOR_ITER 10 (to 14)
4 STORE_FAST 1 (i)
6 LOAD_FAST 1 (i)
8 YIELD_VALUE <-- Pass data through iterator
10 POP_TOP <-- Dispose of None from send()
12 JUMP_ABSOLUTE 2
>> 14 LOAD_CONST 0 (None)
16 RETURN_VALUE
The list comprehension builds the list directly with the high-speed specialized, LIST_APPEND opcode.
The generator runs YIELD_VALUE and POP_TOP but the work isn't done. There needs to be a context switch to list_extend() which then extract the value from the iterator and finally appends it to the list.
Executive summary: there is overhead when passing data through the iterator protocol.
----------
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue32945>
_______________________________________
More information about the Python-bugs-list
mailing list