程式語言:Python
Package:cProfile, pstats
官方文件
功能:分析程式效率
用文本編輯器打開時會亂碼,需用 pstats 分析並輸出
class cProfile.Profile(timer=None, timeunit=0.0, subcalls=True, builtins=True)
profile, cProfile, and pstats – Performance analysis of Python programs.
使用cProfile分析Python程序性能
Package:cProfile, pstats
官方文件
功能:分析程式效率
# 程式呼叫方法 import cProfile import re # cProfile.run(command, filename=None, sort=-1) cProfile.run('re.compile("foo|bar")', filename="result.out", sort="cumulative")
# 命令行 # 文件內容是以二進制的方式保存的,用文本編輯器打開時會亂碼,可用 pstats 分析並輸出 python -m cProfile [-o output_file] [-s sort_order] myscript.py
199 function calls (194 primitive calls) in 0.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 1 0.000 0.000 0.001 0.001 re.py:221(compile) 1 0.000 0.000 0.001 0.001 re.py:277(_compile) 1 0.000 0.000 0.000 0.000 sre_compile.py:227(_compile_charset) 1 0.000 0.000 0.000 0.000 sre_compile.py:255(_optimize_charset) 1 0.000 0.000 0.000 0.000 sre_compile.py:444(_compile_info) 2 0.000 0.000 0.000 0.000 sre_compile.py:545(isstring) 1 0.000 0.000 0.000 0.000 sre_compile.py:548(_code) 1 0.000 0.000 0.000 0.000 sre_compile.py:563(compile) 3/1 0.000 0.000 0.000 0.000 sre_compile.py:70(_compile)輸出每列的具體解釋如下
- ncalls
- 表示函數調用的次數
- 若為兩個數字表示有 recursive 像 3/1
前者 3 表示總調用次數,後者 1 表示主要調用次數(不含本身調用) - tottime
- 表示指定函數的總運行時間,除掉函數中調用子函數的運行時間
- percall
- (第一個percall)等於 tottime/ncalls
- cumtime
- 表示該函數及其所有子函數的調用運行的時間,即函數開始調用到返回的時間
- percall
- (第二個percall)即函數運行一次的平均時間,等於 cumtime/ncalls
- filename:lineno(function)
- 每個函數調用的具體信息,檔名:行數 (函數名)
cProfile
文件內容是以二進制的方式保存的用文本編輯器打開時會亂碼,需用 pstats 分析並輸出
- cProfile.run(command, filename=None, sort=-1)
- command
- pass 到 exec()
可以直接輸入想分析的動作,例:'re.compile("foo|bar") - filename
- 輸出的檔案名
- sort
- 排序的依據
- cProfile.runctx(command, globals, locals, filename=None)
- 可自行輸入所需參數
值 | 意義 |
---|---|
'calls' | 呼叫次數 |
'ncalls' | 呼叫次數 |
'cumulative' | 總調用時間 |
'cumtime' | 總調用時間 |
'file' | 檔名 |
'filename' | 檔名 |
'module' | 檔名 |
'pcalls' | 平均調用時間,不含子函數 |
'line' | 行數 |
'name' | function 名字 |
'nfl' | 表示以 name/file/line 順序排列 |
'stdname' | 同 nfl,但檔名一樣時 lines 3, 20, 40 順序將是 20, 3, 40 |
'time' | 總調用時間,不含子函數 |
'tottime' | 總調用時間,不含子函數 |
import cProfile import re cProfile.runctx('re.compile(text)', globals(), {'text':'foo|bar'})
- 當需要比 cProfile.run() 更精準的操作時,才會用到
import cProfile import re pr = cProfile.Profile() pr.enable() re.compile('foo|bar') pr.disable() pr.print_stats()
- enable()
- 開始分析
- disable()
- 停止分析
- create_stats()
- 停止分析且內部記錄其分析結果
- print_stats(sort=-1)
- 印出分析報表
- dump_stats(filename)
- 輸出分析結果於檔案
- run(cmd)
- 執行後回傳 cProfile.Profile object
- pr.run("re.compile('foo|bar')").print_stats()
- runctx(cmd, globals, locals)
- 執行後回傳 cProfile.Profile object,但可輸入 globals 跟 locals 做為變數
- pr.runctx("re.compile(text)", globals(), {'text':'foo|bar'}).print_stats()
- runcall(func, *args, **kwargs)
- 執行後回傳執行結果,但可輸入 *args 跟 **kwargs 做為參數
import re import cProfile pr = cProfile.Profile() pr.runcall(re.compile, 'foo|bar') # re.compile('foo|bar') pr.print_stats()
分析工具 pstats
# 程式呼叫方法 import pstats # 創建Stats對象 p = pstats.Stats("result.out") # strip_dirs(): 去掉無關的路徑信息 # sort_stats(): 排序,支持的方式和上述的一致 # print_stats(): 打印分析結果,可以指定打印前幾行 # 和直接運行cProfile.run("test()")的結果是一樣的 p.strip_dirs().sort_stats(-1).print_stats() # 按照函數名排序,只打印前3行函數的信息, 參數還可為小數,表示前百分之幾的函數信息 p.strip_dirs().sort_stats("name").print_stats(3) # 按照運行時間和函數名進行排序,只顯示前 50% p.strip_dirs().sort_stats("cumulative", "name").print_stats(0.5) # 如果想知道有哪些函數調用了sum_num,只顯示前 50% p.print_callers(0.5, "sum_num") # 查看test()函數中調用了哪些函數 p.print_callees("test")
# 命令行 python -m pstats result.out 打 help,顯示可用指令如下 Documented commands (type help <topic>): ======================================== EOF add callees callers help quit read reverse sort stats strip
- class pstats.Stats(*filenames or profile, stream=sys.stdout)
- 新舊版本的檔案不見得具有相容性
import re import cProfile, pstats pr = cProfile.Profile() pr.runcall(re.compile, 'foo|bar') with open('output.txt', 'w') as stream: stats = pstats.Stats(pr, stream=stream) stats.print_stats()
- 參數
- *filenames or profile
- 檔案 或 cProfile.Profile object
- stream
- 可以是 stream = open('path/to/output', 'w'),直接寫入檔案
- 方法
- strip_dirs()
- 移除 filename:lineno(function) 中的路徑
- add(*filenames)
- 加入其他分析結果
- dump_stats(filename)
- 輸出分析報表至檔案
- sort_stats(*keys)
- 排序報表
- 可以多個,如 sort_stats('name', 'file', 'line')
- reverse_order()
- 報表序列反轉
- print_stats(*restrictions)
- 輸出分析報表
- *restrictions
- 限制幾筆 (int)
- 限制前多少% (float) 需小於 1
- print_stats(0.1, 'foo:')
- 只輸出前 10%,filename 有 foo: 的
- print_stats('foo:', 0.1)
- 只輸出 filename 有 foo: 的前 10%
- print_callers(*restrictions)
- 輸出哪些函數調用過指定函數的資訊
- p.print_callers('init', 10)
- 前十筆 init 被哪些函數調用過的資訊
- print_callees(*restrictions)
- 輸出指定函數調用過哪些函數的資訊
- p.print_callees('init', 0.2)
- 前 20% init 調用過哪些函數的資訊
參考
使用cProfile分析Python程序性能profile, cProfile, and pstats – Performance analysis of Python programs.
使用cProfile分析Python程序性能
留言
張貼留言