profiler是一個程序,用來描述運行時的程序性能,並且從不同方面提供統計數據加以表述。Python中含有3個模塊提供這樣的功能,分別是cProfile, profile和pstats。這些分析器提供的是對Python程序的確定性分析。同時也提供一系列的報表生成工具,允許用戶快速地檢查分析結果。
Python標准庫提供了3個不同的性能分析器:
- cProfile,推薦給大部分的用戶,是C的一個擴展應用,因為其合理的運行開銷,所以適合分析運行時間較長的。是基於lsprof。
- profile,一個純python模塊,它的接口和cProfile一致。在分析程序時,增加了很大的運行開銷。如果你想擴展profiler的功能,可以試着繼承這個模塊
- hotshot, 一個試驗性的c模塊,關注減少分析時的運行開銷,但是是以需要更長的數據后處理的次數為代價。不過這個模塊不再被維護,也有可能在新的python版本中被棄用。
比如在flask,可以這樣使用
from app import app
if __name__ == '__main__':
app.debug = True
import cProfile
cProfile.run("app.run(host='127.0.0.1', port=80)", "c:\\wwww123.txt")
import pstats
p = pstats.Stats("c:\\wwww123.txt")
p.sort_stats("time").print_stats(20)
#app.run(host="127.0.0.1", port=80)
if
__name__
=
=
"__main__"
:
import
cProfile
#直接把分析結果打印到控制台
cProfile.run(
"foo()"
)
#把分析結果保存到文件中,不過內容可讀性差...需要調用pstats模塊分析結果
cProfile.run(
"foo()"
,
"result"
)
#還可以直接使用命令行進行操作
#>python -m cProfile myscript.py -o result
import
pstats
#創建Stats對象
p
=
pstats.Stats(
"result"
)
#這一行的效果和直接運行cProfile.run("foo()")的顯示效果是一樣的
p.strip_dirs().sort_stats(
-
1
).print_stats()
#strip_dirs():從所有模塊名中去掉無關的路徑信息
#sort_stats():把打印信息按照標准的module/name/line字符串進行排序
#print_stats():打印出所有分析信息
#按照函數名排序
p.strip_dirs().sort_stats(
"name"
).print_stats()
#按照在一個函數中累積的運行時間進行排序
#print_stats(3):只打印前3行函數的信息,參數還可為小數,表示前百分之幾的函數信息
p.strip_dirs().sort_stats(
"cumulative"
).print_stats(
3
)
#還有一種用法
p.sort_stats(
'time'
,
'cum'
).print_stats(.
5
,
'foo'
)
#先按time排序,再按cumulative時間排序,然后打倒出前50%中含有函數信息
#如果想知道有哪些函數調用了bar,可使用
p.print_callers(
0.5
,
"bar"
)
#同理,查看foo()函數中調用了哪些函數
p.print_callees(
"foo"
)
Stats有若干個函數,這些函數組合能給我們輸出不同的profile報表,功能非常強大。下面簡單地介紹一下這些函數:
strip_dirs() | 用以除去文件名前名的路徑信息。 |
add(filename,[…]) | 把profile的輸出文件加入Stats實例中統計 |
dump_stats(filename) | 把Stats的統計結果保存到文件 |
sort_stats(key,[…]) | 最重要的一個函數,用以排序profile的輸出 |
reverse_order() | 把Stats實例里的數據反序重排 |
print_stats([restriction,…]) | 把Stats報表輸出到stdout |
print_callers([restriction,…]) |
輸出調用了指定的函數的函數的相關信息
|
print_callees([restriction,…]) | 輸出指定的函數調用過的函數的相關信息 |
profile的統計結果分為ncalls, tottime, percall, cumtime, percall, filename:lineno(function)等若干列:
ncalls | 函數的被調用次數 |
tottime | 函數總計運行時間,除去函數中調用的函數運行時間 |
percall | 函數運行一次的平均時間,等於tottime/ncalls |
cumtime | 函數總計運行時間,含調用的函數運行時間 |
percall | 函數運行一次的平均時間,等於cumtime/ncalls |
filename:lineno(function) | 函數所在的文件名,函數的行號,函數名 |