[英]Python generators timeit
我試圖理解許多教程中的Python生成器,而這些教程告訴他們它們比例如遍歷列表要快得多,所以我嘗試一下,編寫了一個簡單的代碼。 我沒想到時差會那么大,有人能解釋我為什么嗎? 也許我在這里做錯了。
def f(limit):
for i in range(limit):
if(i / 7.0) % 1 == 0:
yield i
def f1(limit):
l = []
for i in range(limit):
if(i / 7.0) % 1 == 0:
l.append(i)
return l
t = timeit.Timer(stmt="f(50)", setup="from __main__ import f")
print t.timeit()
t1 = timeit.Timer(stmt="f1(50)", setup="from __main__ import f1")
print t1.timeit()
結果:t = 0.565694382945 t1 = 11.9298217371
您沒有公平地比較f
和f1
。
您的第一個測試只是測量Python 構造生成器對象所花費的時間。 但是,它永遠不會迭代該對象,這意味着f
內的代碼永遠不會實際執行(生成器僅在對其進行迭代時才執行其代碼)。
但是,您的第二項測試將測量調用f1
所需的時間。 意思是,它計算函數構造列表l
,運行for循環直至完成,調用list.append
多次,然后返回結果。 顯然,這將比僅生成生成器對象慢得多。
為了公平起見,將生成器f
轉換為列表以使其耗盡:
t = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f")
這將導致它被完全迭代,這意味着f
的代碼現在將被執行。
您正在計時創建生成器對象所需的時間。 創建一個代碼實際上並不會執行任何代碼,因此實際上您正在計時一種精心設計的不執行任何操作的方法。
修復此問題后,您會發現生成器運行完成時通常會稍微慢一些。 它們的優勢在於,它們不需要一次將所有元素存儲在內存中,並且可以中途停止。 例如,當您有一系列布爾值並且要檢查它們是否為真時,使用列表時,首先要計算所有值並創建它們的列表,然后再檢查真值,而使用生成器時,您可以:
https://wiki.python.org/moin/Generators在“提高性能”部分下有一些不錯的信息。 盡管創建一個生成器可能會花費一些時間,但它具有許多優點。
這是一個有關創建生成器和迭代器的好教程, 網址為http://sahandsaba.com/python-iterators-generators.html 。 看看這個!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.