Profile tutorial–性能分析
參考: http://docs.cython.org/en/latest/src/tutorial/profiling_tutorial.html
github代碼: https://github.com/chenyangMl/cython-pro/tree/master/Profile
性能分析:指通過性能測試報告對所寫代碼進行整體和局部(函數)的運行效率分析,爲後續的性能優化提供決策支持。
1. 純python的性能分析
分析案例:
-
1 自己寫的python代碼文件calc_pi.py
# calc_pi.py def recip_square(i): return 1. / i ** 2 def approx_pi(n=10000000): val = 0. for k in range(1, n + 1): val += recip_square(k) return (6 * val) ** .5
-
2 編寫性能分析腳本python_profile.py
# python_profile.py import pstats, cProfile import calc_pi cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") s = pstats.Stats("Profile.prof") s.strip_dirs().sort_stats("time").print_stats()
運行性能分析腳步,結果如下:
10000004 function calls in 3.361 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 10000000 2.439 0.000 2.439 0.000 calc_pi.py:3(recip_square) 1 0.922 0.922 3.361 3.361 calc_pi.py:6(approx_pi) 1 0.000 0.000 3.361 3.361 {built-in method builtins.exec} 1 0.000 0.000 3.361 3.361 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Type | 備註 |
---|---|
ncalls | 函數被調用的次數 |
tottime | 函數內部消耗的總時間 |
percall | 函數的平均調用時間,tottime/ncalls |
cumtime | 之前所有子函數消費時間的累計和 |
filename:lineno(function) | 被分析函數所在文件名、行號、函數名。 |
2. Cython的性能分析
-
1、自己的Cython代碼,calc_pi.pyx文件
# cython: profile=True # calc_pi.pyx def recip_square(int i): return 1. / i ** 2 def approx_pi(int n=10000000): cdef double val = 0. cdef int k for k in range(1, n + 1): val += recip_square(k) return (6 * val) ** .5
注意 上述第一行
# cython: profile=True
是顯示告訴Cython啓用分析,必須加上。 -
2、性能分析腳步cython_profile.py
# cython_profile.py import pstats, cProfile import pyximport pyximport.install() import calc_pi cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") s = pstats.Stats("Profile.prof") s.strip_dirs().sort_stats("time").print_stats()
運行性能分析腳步,結果如下:
10000004 function calls in 3.146 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 10000000 2.233 0.000 2.233 0.000 calc_pi.py:2(recip_square) 1 0.914 0.914 3.146 3.146 calc_pi.py:5(approx_pi) 1 0.000 0.000 3.146 3.146 {built-in methodcy builtins.exec} 1 0.000 0.000 3.146 3.146 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
當需要cProfile.runctx進行傳參性能分析時,通過global或local將參數以字典的形式傳入。
cProfile.runctx("calc_pi.approx_pi(n)", globals(), locals={"n":15000}, "Profile.prof")
-
3 基於性能分析內容進行代碼優化。
-
4 關閉對某個函數的性能分析,只需要在函數加一個
@cython.profile(False)
的裝飾器即可,如停止對函數recip_square的性能分析:cimport cython @cython.profile(False) def recip_square(int i): return 1. / i ** 2