無意中被問到代碼執行效率的問題,那就總結一下檢測代碼執行效率的幾種方式:
一、裝飾器
在函數上加裝飾器,來得到函數的執行時間。
def cst_time(func, *args, **kwargs): def wrapper(*args, **kwargs): start = time.time() ret = func(*args, **kwargs) end = time.time() timestrap = end -start print('function %s running time is %s'%(func.__name__,timestrap)) return ret return wrapper
二、timeit模塊
用timeit模塊來計算代碼執行時間:
python3 -m timeit -n 4 -r 5 -s "import binaryTree" "binaryTree" #其中binaryTree表示python腳本文件名 或 python3 -m timeit -n 4 -r 5 -s "import binaryTree" "binaryTree.functionname" #可以指定腳本中某個具體的函數
參數:
-m mod : run library module as a script (terminates option list)
執行結果:
4 loops, best of 5: 0.0792 usec per loop
這表示測試了4次,平均每次測試重復5次,最好的測試結果是0.0792秒。
如果不指定測試或重復次數,默認值為10次測試,每次重復5次。
三、Linux的time命令
time -p python3 multiTree.py
執行結果:
real 0.09 # 執行腳本的總時間 user 0.04 # 執行腳本消耗的CPU時間 sys 0.00 # 執行內核函數消耗的時間 # real - (user + sys)的時間差,就是消耗在I/O等待和執行其他任務消耗的時間。
四、cProfile模塊
如果想知道每個函數消耗的多少時間,以及每個函數執行了多少次,可以用CProfile模塊。
python3 -m cProfile -s cumulative multiTree.py
執行結果:
五、line_Profiler模塊
使用line_Profiler可以給出執行每行代碼所占用的CPU時間。
$ sudo pip3 install line_Profiler
用@profile 指定去檢測那個函數,不需要導入模塊。
@profile def random_sort2(n): l = [random.random() for i in range(n)] l.sort() return l if __name__ == "__main__": random_sort2(2000000)
可以通過如下命令逐行掃描每行代碼的執行情況:
$ kernprof -l -v timing_functions.py
其中-l表示逐行解釋,-v表示表示輸出詳細結果。通過這種方法,我們看到構建數組消耗了44%的計算時間,而sort()方法消耗了剩余的56%的時間。
六、memory_profiler模塊
逐行檢測每行代碼內存的使用的情況。但使用這個模塊會讓代碼運行更慢。
$ sudo pip3 install memory_profiler
安裝 psutil模塊,會讓memory_profiler運行更快。
$ sudo pip3 install psutil
在函數上加 @profile 裝飾器來指定需要追蹤的函數。
執行如下命令,查看結果:
$ python3 -m memory_profiler timing_functions.py
七、guppy模塊
通過這個包可以知道在代碼執行的每個階段中,每種類型(str、tuple、dict等)分別創建了多少對象。
$ pip3 install guppy
將其添加到代碼中:
from guppy import hpy def random_sort3(n): hp = hpy() print( "Heap at the beginning of the functionn", hp.heap()) l = [random.random() for i in range(n)] l.sort() print( "Heap at the end of the functionn", hp.heap()) return l if __name__ == "__main__": random_sort3(2000000)
執行命令:
$ python3 timing_functions.py
查看結果:
-----------------------------------------------------------------------------------------------------------------------------------------------------