5種方法對python程式程式碼做效能分析和計時統計
python程式碼執行時間統計
以下方法分別針對 程式碼塊、程式碼程式檔案、 函式 進行效能計時統計
一、time.time() 或者 datetime.datetime.now()
返回當前時間的時間戳 如 1524302633.980187
兩次時間相減,程式碼執行所需的 掛鐘時間,也就是命令開始執行到結束的時間。
import time
start = time.time()
print("Hello World")
time.sleep(2)
end = time.time()
print(end - start)
輸出
Hello World
2.0038700103759766
二、time.clock()
clock() 函式以浮點數計算的秒數返回當前的CPU時間。用來衡量不同程式的耗時,比time.time()更有用。
在win系統下,這個函式返回的是真實時間(wall time),而在Unix/Linux下返回的是CPU時間。
#檔案 test.py
import time
start = time.clock()
print("Hello World")
time.sleep(2)
end = time.clock()
print(end - start)
linux 下輸出
Hello World
0.00020299999999999485
time.clock(),python 3.3版本以後這個函式被廢棄了,但是這個函式仍然可以使用。
三、time
在linux下對整個程式做計時統計
time python test.py
如果time 命令報錯,可以使用/usr/bin/time 而不是time
/usr/bin/time -p python test.py
輸出內容
real 0m2.057s
user 0m0.033s
sys 0m0.011s
real 記錄了整體的耗時
user 記錄了 CPU花在任務上的時間,但不包括核心函式花費的時間
sys 記錄了核心函式花費的時間
對user和sys 相加就得到了CPU總共花費的時間。而這個時間和real的差則有可能是花費在等待IO上。
可以開啟–verbose開關來獲得更多輸出資訊
/usr/bin/timee --verbose python
四、cProfile
python -m cProfile test.py
python -m cProfile -o profile.stats test.py
生成一個統計檔案然後通過python進行分析
import pstats
p = pstats.Stats(“profile.stats”)
p.print_stats()
Hello World
0.00010600000000000193
8 function calls in 2.005 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.005 2.005 test.py:3(<module>)
1 0.000 0.000 2.005 2.005 {built-in method builtins.exec}
2 0.000 0.000 0.000 0.000 {built-in method builtins.print}
2 0.000 0.000 0.000 0.000 {built-in method time.clock}
1 2.005 2.005 2.005 2.005 {built-in method time.sleep}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
用runsnakerun 對cProfile的輸出進行視覺化
pip install runsnake 來安裝,需要wxPython,在virtualenv下安裝會比較麻煩。沒試過,記錄下。
來自書籍《python高效能程式設計》
五、 timeit
from timeit import timeit
timeit('math.sqrt(2)', 'import math', number=100000)
六、裝飾器–對函式進行計時統計
定義裝飾器timethis
將裝飾器放在函式定義之前,就能得到對應函式的計時資訊
from functools import wraps
import time
def timethis(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
r = func(*args, **kwargs)
end = time.perf_counter()
print('{}.{} : {}'.format(func.__module__, func.__name__, end - start))
return r
return wrapper
@timethis
def ts():
time.sleep(2)
print("Hello World")
ts()
輸出
Hello World
main.ts : 2.0007375059940387
七、用line_profiler進行逐行分析
用cProfile找到需要分析的函式,然後用line_profiler對函式進行分析
pip install line_profiler
執行kernprof 逐行分析被修飾函式的CPU開銷
kernprof.py -l -v test.py
-v 顯示輸出
-l 代表逐行分析而不是逐函式分析
備註
使用time.perf_counter() 能夠提供給定平臺上精度最高的計時器,但是,它計算的仍然是時鐘時間,很多因素會影響到它的精確度,比如機器負載。
如果你對於執行時間更感興趣,使用time.process_time() 來代替它。