为什么列表理解如此之快?

这个问题在这里已经有了答案:

  • Python列表理解昂贵1个答案

  • 列表推导在这里执行得更好,因为您不需要加载列表的append属性并将其作为函数调用!*

    考虑下面的例子:

    >>> import dis
    >>> def f1():
    ...   for i in range(5):
    ...      l.append(i)
    ... 
    >>> def f2():
    ...   [i for i in range(5)]
    ... 
    >>> dis.dis(f1)
      2           0 SETUP_LOOP              33 (to 36)
                  3 LOAD_GLOBAL              0 (range)
                  6 LOAD_CONST               1 (5)
                  9 CALL_FUNCTION            1
                 12 GET_ITER            
            >>   13 FOR_ITER                19 (to 35)
                 16 STORE_FAST               0 (i)
    
      3          19 LOAD_GLOBAL              1 (l)
                 22 LOAD_ATTR                2 (append)
                 25 LOAD_FAST                0 (i)
                 28 CALL_FUNCTION            1
                 31 POP_TOP             
                 32 JUMP_ABSOLUTE           13
            >>   35 POP_BLOCK           
            >>   36 LOAD_CONST               0 (None)
                 39 RETURN_VALUE        
    >>> dis.dis(f2)
      2           0 BUILD_LIST               0
                  3 LOAD_GLOBAL              0 (range)
                  6 LOAD_CONST               1 (5)
                  9 CALL_FUNCTION            1
                 12 GET_ITER            
            >>   13 FOR_ITER                12 (to 28)
                 16 STORE_FAST               0 (i)
                 19 LOAD_FAST                0 (i)
                 22 LIST_APPEND              2
                 25 JUMP_ABSOLUTE           13
            >>   28 POP_TOP             
                 29 LOAD_CONST               0 (None)
                 32 RETURN_VALUE        
    >>> 
    

    你可以看到,在字节码22中,我们在第一个函数中有一个append属性,因为在使用列表理解的第二个函数中没有这样的事情。

    还要注意,你将在每次迭代中append attr加载,因此它使你的代码比使用列表理解的第二个函数慢大约2倍。

    此外,根据您的Python和代码,列表内涵可能会遇到比手动更快for ,因为他们的迭代解释里面C语言的速度进行 ,而不是手动Python代码循环语句(通常大约快两倍)。 特别是对于较大的数据集,使用此表达式通常具有主要的性能优势。**


    *你可以阅读更多关于列表理解的效率

    ** Mark Lutz学习Python


    即使不考虑查找和加载append函数所花费的时间,列表理解仍然更快,因为列表是以C语言创建的,而不是一次在Python中构建一个项目。

    # Slow
    timeit.timeit(stmt='''
        for i in range(10000):
            t.append(i)''', setup='t=[]', number=10000)
    
    # Faster
    timeit.timeit(stmt='''
        for i in range(10000):
            l(i)''', setup='t=[]; l=t.append', number=10000)
    
    # Faster still
    timeit.timeit(stmt='t = [i for i in range(10000)]', number=10000)
    

    引用这篇文章,是因为listappend属性没有被查找,加载并作为一个函数被调用,这需要时间并且会叠加迭代。

    链接地址: http://www.djcxy.com/p/69947.html

    上一篇: Why is list comprehension so faster?

    下一篇: python:loop vs comprehension