[轉]Python Profile 工具效能分析
阿新 • • 發佈:2019-02-06
最近碰到“程式速度大大降低”的說法,還是直接用資料說明比較有信服力,以及可以找出真正問題所在。
Python自帶了幾個效能分析的模組:profile、cProfile和hotshot,使用方法基本都差不多,無非模組是純Python還是用C寫的。
本文示例基於cProfile模組,先寫點測試程式碼(test1.py):
import time
def func1():
sum = 0
for i in range(1000000):
sum += i
def func2():
time.sleep(10)
func1()
func2()
執行cProfile命令如下:
$ python -m cProfile -o test1.out test1.py
這裡是以模組方式直接儲存profile結果,當然也可以在程式中引入cProfile模組。
好了,上面的測試程式大概執行10秒左右,可以看下最終的效能分析資料。
$ python -c "import pstats; p=pstats.Stats('test1.out'); p.print_stats()"
Wed Aug 28 22:19:45 2013 test1.out
6 function calls in 10.163 seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno( function)
1 0.024 0.024 10.163 10.163 test1.py:1(<module>)
1 10.001 10.001 10.001 10.001 {time.sleep}
1 0.092 0.092 0.138 0.138 test1.py:3(func1)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 10.001 10.001 test1.py:8 (func2)
1 0.046 0.046 0.046 0.046 {range}
分析的資料還很清晰和簡單的吧,大概能看出幾列資料的意思,重點關注下時間和函式呼叫次數,再來排個序:
$ python -c "import pstats; p=pstats.Stats('test1.out'); p.sort_stats('time').print_stats()"
Wed Aug 28 22:19:45 2013 test1.out
6 function calls in 10.163 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 10.001 10.001 10.001 10.001 {time.sleep}
1 0.092 0.092 0.138 0.138 test1.py:3(func1)
1 0.046 0.046 0.046 0.046 {range}
1 0.024 0.024 10.163 10.163 test1.py:1(<module>)
1 0.000 0.000 10.001 10.001 test1.py:8(func2)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
可以看出測試程式中最耗費時間點是:time.sleep和range。
sort_stats支援一下引數:
calls, cumulative, file, line, module, name, nfl, pcalls, stdname, time
pstats模組還支援互動式:
$ python -m pstats test1.out
Welcome to the profile statistics browser.
test1.out% ### help 或者輸入字母按下tab,可以補全的
test1.out% stats 10
這裡似乎告一段落了,只是輸出式的效能分析似乎有點乏味,開源世界這麼美好,肯定會有些更美觀和帥氣的方法吧。
一步步來,先安裝依賴項(請選擇對應系統平臺):
PS:Ubuntu系統請注意請注意,pstats模組因為某些原因不在Python包中,需要單獨安裝:python-profiler包
裝好依賴後,如此這番:
$ ./gprof2dot.py -f pstats test1.out | dot -Tpng -o test1.png
看看test1.png,一切都瞭然於心了吧。。。
END