2014-11-14 12 views
0

在Python中,哪個更快?每個Python比索引更快?

for word in listOfWords: 
    doSomethingToWord(word) 
for i in range(len(listOfWords)): 
    doSomethingToWord(listOfWords[i]) 

當然,我會使用的xrange在Python 2.x版本

我的假設是1.比2快。如果是這樣,爲什麼?

+0

你可以自己測試;)。並且是1更快。 –

+0

2,對於每個我你calaculate列表的長度。首先是更快 –

+1

由於您可能猜測的原因,您的假設可能是正確的 - 它可以優化C代碼中的項目查找。在這兩種情況下,你都要在本地對象上調用'next',以便兩種方式都很快(儘管xrange仍然需要做更多的計算以處理啓動,停止和跨步等)......但是在後者中情況下,您需要執行_indexing_對象的額外步驟,您以前不必執行此操作。 – mgilson

回答

3

不要問這個問題的,你總是可以嘗試做他們自己。這並不難。 超級簡單的基準測試會告訴你的差異。

from datetime import datetime 
arr = [4 for _ in xrange(10**8)] 

startTime = datetime.now() 
for i in arr: 
    i 
print datetime.now() - startTime 

startTime = datetime.now() 
for i in xrange(len(arr)): 
    arr[i] 
print datetime.now() - startTime 

在我的機器,它是:

0:00:04.822513 
0:00:05.676396 

注意你迭代的名單應該是相當大的看出差別。第二個循環更長,因爲每次需要通過索引(arr[i])進行查找並且還要生成xrange的值。

請不要花太多時間在大多數無用的微優化中,而是試着看看是否可以提高內循環函數的計算複雜度。

+1

使用'timeit'會更好 – glglgl

+1

@glglgl很多事情會更好。例如說這樣的基準沒有意義,因爲許多其他事情更重要的是微觀優化。日期時間是否完成這項工作?是。它是否顯示OP要求的內容?是。我解釋爲什麼?是。我能告訴做什麼更好嗎?是。所以答案就夠了。 –

+1

雖然timeit可能會更好,但我選擇這個答案爲正確答案,因爲他解釋了答案中的原因。沒有人做過。 (儘管有人在我的問題的評論中做過) – CamHart

4

使用Python的timeit模塊來回答這樣一個問題:

[email protected]:~$ python -m timeit -s "listOfWords=['hello']*1000" "for word in listOfWords: len(word)" 
10000 loops, best of 3: 37.2 usec per loop 
[email protected]:~$ python -m timeit -s "listOfWords=['hello']*1000" "for i in range(len(listOfWords)): len(listOfWords[i])" 
10000 loops, best of 3: 52.1 usec per loop 
2

只需嘗試timeit

In [2]: def solve(listOfWords): 
     for word in range(len(listOfWords)): 
       pass 
    ...:  

In [3]: %timeit solve(xrange(10**5)) 
100 loops, best of 3: 4.34 ms per loop 

In [4]: def solve(listOfWords): 
     for word in listOfWords: 
       pass 
    ...:  

In [5]: %timeit solve(xrange(10**5)) 
1000 loops, best of 3: 1.84 ms per loop 
1

除了速度上的優勢,1是「清潔的前瞻性」,同時也將對於不支持LEN,即發電機表情和發電機功能的結果序列工作。要使用解決方案2,首先必須將生成器轉換爲列表,以便獲得其長度(如果可以的話)。但是,如果生成器正在生成所有素數列表,並且doSomething正在查找第一個大於100的值,那該怎麼辦呢?

for num in prime_number_generator(): 
    if num > 100: return num 

無法將其轉換爲第二種形式,因爲此生成器沒有結束。

另外,如果創建列表元素(如從數據庫或遠程Web服務器中獲取數據)非常昂貴會怎樣?如果您在生成的N個值中尋找匹配值,使用#1,您可以在找到匹配項時立即退出,並平均避免產生N/2個值。要使用#2,首先必須生成所有N值才能獲得長度以製作範圍。

Python 3轉換很多內置函數以返回迭代器而不是列表是有原因的 - 它們更靈活。

What is Pythonic? 
"for i in range(len(seq)):"? No. 
Use "for x in seq:"