Python list()与列表理解构建速度 [英] Python list() vs list comprehension building speed
问题描述
这很有趣; list()
强制迭代器获取实际列表比[x for x in someList]
(理解)要快得多.
This is interesting; list()
to force an iterator to get the actual list is so much faster than [x for x in someList]
(comprehension).
这是真实的还是我的测试太简单了? 下面是代码:
Is this for real or is my test just too simple? Below is the code:
import time
timer = time.clock()
for i in xrange(90):
#localList = [x for x in xrange(1000000)] #Very slow, took me 6.8s
localList = list(xrange(1000000)) #Very fast, took me 0.9s
print localList[999999] #make sure list is really evaluated.
print "Total time: ", time.clock() - timer
推荐答案
列表推导以Python字节码执行循环,就像常规的for
循环一样.
The list comprehension executes the loop in Python bytecode, just like a regular for
loop.
list()
调用完全在C代码中进行迭代,这要快得多.
The list()
call iterates entirely in C code, which is far faster.
列表理解的字节码如下:
The bytecode for the list comprehension looks like this:
>>> import dis
>>> dis.dis(compile("[x for x in xrange(1000000)]", '<stdin>', 'exec'))
1 0 BUILD_LIST 0
3 LOAD_NAME 0 (xrange)
6 LOAD_CONST 0 (1000000)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 12 (to 28)
16 STORE_NAME 1 (x)
19 LOAD_NAME 1 (x)
22 LIST_APPEND 2
25 JUMP_ABSOLUTE 13
>> 28 POP_TOP
29 LOAD_CONST 1 (None)
32 RETURN_VALUE
>>
指针大致为您提供了正在执行的循环的边界,因此您需要在Python字节码评估循环中执行一百万个STORE_NAME
,LOAD_NAME
和LIST_APPEND
步骤.
The >>
pointers roughly give you the boundaries of the loop being executed, so you have 1 million STORE_NAME
, LOAD_NAME
and LIST_APPEND
steps to execute in the Python bytecode evaluation loop.
list()
只是通过使用C API进行对象迭代直接从xrange()
迭代中获取值,并且它可以使用xrange()
对象的长度来预先分配列表对象,而不是而不是动态增长.
list()
on the other hand just grabs the values from the xrange()
iterable directly by using the C API for object iteration, and it can use the length of the xrange()
object to pre-allocate the list object rather than grow it dynamically.
这篇关于Python list()与列表理解构建速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!