通過迭代islice(permutations(a), n)是有點快100倍,如果我只是保持一個額外的參考permutations迭代器。在有和沒有額外參考之間交替:
2.1 ms with
202.2 ms without
2.1 ms with
195.8 ms without
2.1 ms with
192.4 ms without
這是怎么回事?
完整代碼(在線試用!):
from timeit import timeit
from itertools import permutations, islice
from collections import deque
a = range(10 ** 7)
n = 10 ** 5
for label in ['with', 'without'] * 3:
if label == 'with':
perms = islice((foo := permutations(a)), n)
else:
perms = islice(permutations(a), n)
next(perms)
t = timeit(lambda: deque(perms, 0), number=1)
print('%5.1f ms ' % (t * 1e3), label)
uj5u.com熱心網友回復:
我才明白為什么。如果我不保留參考,則迭代器及其所有需要在計時結束時進行垃圾收集,并將其包含在時間中。
請注意,我構建排列的串列非常大。所以每個排列都非常大。所以permutations迭代器有一個大的結果元組和內部狀態資料結構,而且我還有數百萬個范圍內的整數物件。所有這些都必須清理干凈。
當我將ato的大小減半時a = range(10 ** 7 // 2),“沒有”額外參考的時間下降到大約一半(100 毫秒)。
當我將ato的大小加倍時a = range(10 ** 7 * 2),“沒有”額外參考的時間大約加倍(超過 400 毫秒)。
這兩種變化都不會影響“with”時間(始終在 2 ms 左右)。
如果有人想知道為什么我要構建如此大的串列的排列:我正在研究permutations提供所有 n所需的時間!n 個元素的排列。有人可能認為它需要 O(n × n!),因為這是整體結果大小。但是如果可以,它會重用和修改其結果元組,因此它不會從頭開始構建每個排列,而只需要稍微更新它。所以我用大 n測驗了它,以便看到它何時可以和不能重用其結果元組之間的巨大速度差異。如果可以的話,它確實要快得多,而且似乎只需要 O(n!) 時間來提供所有排列。它似乎平均只改變 2.63 個元素 從一種排列到下一種排列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/394329.html
下一篇:如何對2個檔案執行內部聯接
