1. 程式人生 > >5種方法對python程式程式碼做效能分析和計時統計

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

test.py

四、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() 來代替它。