介紹
profiler是一個程式,用來描述運作時的程式性能,并且從不同方面提供統計資料加以表述。
Python中含有3個子產品提供這樣的功能,分别是cProfile,profile和pstats。這些分析器提供的是對Python程式的确定性分析。同時也提供一系列的報表生成工具,允許使用者快速地檢查分析結果。
Python标準庫提供了3個不同的性能分析器:
- cProfile,推薦給大部分的使用者,是C的一個擴充應用,因為其合理的運作開銷,是以适合分析運作時間較長的。是基于lsprof。
- profile,一個純python子產品,它的接口和cProfile一緻。在分析程式時,增加了很大的運作開銷。如果你想擴充profiler的功能,可以試着繼承這個子產品
- hotshot, 一個試驗性的c子產品,關注減少分析時的運作開銷,但是是以需要更長的資料後處理的次數為代價。不過這個子產品不再被維護,也有可能在新的python版本中被棄用。
實踐
源碼
from random import randint
from cProfile import Profile
import pstats
def insert_sort(data):
result=[]
for value in data:
insert_value(result,value)
return result
def insert_value(result,value):
for i,existing in enumerate(result):
if existing > value:
result.insert(i,value)
return
result.append(value)
def main():
max_size=**
data=[randint(,max_size) for _ in range(max_size)]
test= lambda :insert_sort(data)
return test
使用cProfile進行分析
分析代碼:
def anylize_by_cprofile():
profile=Profile()
profile.runcall(main())
stats=pstats.Stats(profile)
stats.strip_dirs() #從所有子產品名中去掉無關的路徑資訊
stats.sort_stats('cumulative')
stats.print_stats()
anylize_by_cprofile()
分析結果:
[email protected]:~/pdb_test# python test.py
20003 function calls in 1.195 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
test.py:(<lambda>)
test.py:(insert_sort)
test.py:(insert_value)
{method 'insert' of 'list' objects}
{method 'append' of 'list' objects}
{method 'disable' of '_lsprof.Profiler' objects}
結果說明
- ncalls:總的調用次數
- totime:消耗的時間,不包括調用其他函數的時間
- tottime percall:每次調用該函數的時間,不包括調用其他函數的時間
- cumtime:消耗的總時間,包括調用其他函數的實踐
- cumtime percall:每次調用該函數的時間,包括調用其他函數的時間
不足:
上面的資訊隻是列出了每個函數的執行資訊,但是沒有列出調用關系,如果想檢視調用關系,可以執行stats.print_callers()方法,結果如下:
Ordered by: cumulative time
Function was called by...
ncalls tottime cumtime
test.py:(<lambda>) <-
test.py:5(insert_sort) <- 1 0.004 1.221 test.py:21(<lambda>)
test.py:(insert_value) <- 10000 1.199 1.217 test.py:5(insert_sort)
{method 'insert' of 'list' objects} <- 9992 0.018 0.018 test.py:11(insert_value)
{method 'append' of 'list' objects} <- 8 0.000 0.000 test.py:11(insert_value)
{method 'disable' of '_lsprof.Profiler' objects} <-
其他方式
在GUI的系統中,還可以通過更加進階的方式進行分析與調試,例如使用RunSnakeRun,或是KCachegrind,詳細說明可參見:http://blog.jobbole.com/52090/