但是究竟哪一種方法效能比較好呢?以下是一個範例程式可以做個比較:
import time, sys reps = 10000 repsList = range(reps) def tester(func, *args): startTime = time.time() for i in range(reps): func(*args) elapsed = time.time() - startTime return elapsed def forLoop(): res = [] for x in repsList: res.append(abs(x)) def listComprehension(): res = [abs(x) for x in repsList] def mapFunction(): res = list(map(abs, repsList)) print (sys.version) tests = (forStatement, listComprehension, mapFunction) for testfunc in tests: print (testfunc.__name__.ljust(20), '=>', tester(testfunc))這段範例程式會用三種方法分別建立一個內含10000個element的list,並且對每個element執行內建函式abs()
以下是程式執行結果,執行環境為Python 3.2.2
3.2.2 (default, Dec 23 2011, 11:21:15) [GCC 4.6.1] forLoop => 0.0016720294952392578 listComprehension => 0.0008997917175292969 mapFunction => 0.0007519721984863281由以上執行結果可知map最快、list comprehension次之、for loop大概要多花前面兩種方法一倍的時間才能執行完
為什麽map和list comprehension會跑這麼快呢?
其實是因為這兩種方法都有經過Python直譯器的最佳化,在執行時很接近C程式碼跑得速度
而for loop沒有經過最佳化直接在Python直譯器中執行,自然就跑得比較慢
以上範例是針對Python內建函式(abs)所做的測試,如果改用user自己定義的函式結果會不會不一樣呢?
下列範例會把list中的element都加上1
import time, sys reps = 10000 repsList = range(reps) def tester(func, *args): startTime = time.time() for i in range(reps): func(*args) elapsed = time.time() - startTime return elapsed def forLoop(): res = [] for x in repsList: res.append(x + 1) def listComprehension(): res = [x + 1 for x in repsList] def mapFunction(): res = list(map((lambda x : x + 1), repsList)) print (sys.version) tests = (forLoop, listComprehension, mapFunction) for testfunc in tests: print (testfunc.__name__.ljust(20), '=>', tester(testfunc))
3.2.2 (default, Dec 23 2011, 11:21:15) [GCC 4.6.1] forLoop => 0.0016200542449951172 listComprehension => 0.0009100437164306641 mapFunction => 0.0018360614776611328執行結果出乎意料,map竟然變得比fop loop還慢。而list comprehension還是一樣快了快一倍
由此結果可知,Python直譯器當map裡頭放的不是內建函式時,並不會做最佳化的動作
當使用user自己定義的函式時,用list comprehension才能得到最佳的效能
這篇文章結論如下:
1. 當用到內建函式時,使用map可以得到最佳的效能
2. 除了1的case以外,盡量使用list comprehension才可以得到最佳的效能
3. for loop不管在什麽情況下都是跑最慢的
4. 最重要的是除非有特殊效能的考量,否則以上這三種方法盡量優先考慮Python程式的可讀性
Reference: Learning Python, 4e
喜歡你的筆記
回覆刪除24 : tests = (forLoop, listComprehension, mapFunction)
回覆刪除