簡體   English   中英

為什么列表理解比 for 循環慢?

[英]Why is list comprehension slower than a for loop?

為什么 for 循環的追加速度比列表理解快 For Loop Time: 7.214778099999876 List Comprehension Time: 7.4003780000002735

代碼 1:

import timeit

mycode = '''
new_list=[]
x=[1,2,3,4,5]
for obj in x:
    if obj %2==0:
        new_list.append(obj)
'''
 
print (timeit.timeit(stmt = mycode,
                     number = 10000000))

代碼 2:

import timeit

mycode = '''
x=[1,2,3,4,5]
new_list=[obj for obj in x if obj %2==0]
'''

print (timeit.timeit(stmt = mycode,
                     number = 10000000))

當涉及到重復附加時,我預計 for 循環會比列表理解慢,但事實並非如此。

這是因為列表理解版本的啟動開銷更大 與基本循環相比,列表越大,列表理解越快。 實際上,使用x=list(range(15))時,列表理解在我的機器上快了 10%,而對於提供的輸入則慢了 10%。 使用x=list(range(1000)) ,列表理解比其他版本快 25%。

如果你反匯編這些 python 函數,你會看到,列表理解編譯成一個單獨的代碼 object,它有自己的成本。

如果您跟蹤 memory 分配,它們是相同的。

您可以使用以下代碼檢查分配

import tracemalloc
tracemalloc.start()

def a():
    new_list = []
    x = [1, 2, 3, 4, 5]
    for obj in x:
        if obj % 2 == 0:
            new_list.append(obj)


def b():
    x = [1, 2, 3, 4, 5]
    new_list = [obj for obj in x if obj % 2 == 0]

a()
b()

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

print("[ Top 10 ]")
for stat in top_stats[:10]:
    print(stat)

結果是

[ Top 10 ]
xxx:20: size=144 B, count=1, average=144 B
xxx:12: size=144 B, count=1, average=144 B

和字節碼

import dis
print(dis.dis(a))
print('----------------')
print(dis.dis(b))

你會看到類似的東西

Disassembly of <code object <listcomp> at 0x1012d1790, file "xxx", line 18>:
 18           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                10 (to 26)
              6 STORE_FAST               1 (obj)
              8 LOAD_FAST                1 (obj)
             10 LOAD_CONST               0 (2)
             12 BINARY_MODULO
             14 LOAD_CONST               1 (0)
             16 COMPARE_OP               2 (==)
             18 POP_JUMP_IF_FALSE        2 (to 4)
             20 LOAD_FAST                1 (obj)
             22 LIST_APPEND              2
             24 JUMP_ABSOLUTE            2 (to 4)
        >>   26 RETURN_VALUE

在 b 的情況下,但在 a 的情況下不是,它有很多額外的命令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM