[英]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.