Python list() vs 列表理解构建速度

Python list() vs list comprehension building speed

这很有趣; list() 强制迭代器获取实际列表比 [x for x in someList](理解)快得多。

这是真的还是我的测试太简单了? 下面是代码:

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 循环一样。

list() 调用完全在 C 代码中迭代,速度要快得多。

列表理解的字节码如下所示:

>>> 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        

>> 指针大致给出了正在执行的循环的边界,因此您有 100 万个 STORE_NAMELOAD_NAMELIST_APPEND 步要在Python 字节码评估循环。

另一方面,

list() 只是通过使用 C API 直接从 xrange() 可迭代对象中获取值,它可以使用 xrange() 对象预分配列表对象而不是动态增长它。

这似乎不再成立(我检查了 Python 3.7-3.10)。 列表理解比列表函数更快。 我听说 3.10 和 3.11 也会有加速的传闻。