line_profile逐行代码分析
使用line_profiler查看api接口函數每行代碼執行時間
</div>
項目情景描述:
在restful架構風格的項目交付測試的過程中,某接口出現 請求超時導致的http 502 Bad Gateway,于是開始排查具體是接口函數中的哪行代碼或函數 響應時間過長導致的502錯誤。
剛開始的解決方法:
土鱉式的導入 time模塊進行時間計算,從而查出具體響應時間過長的位置
如下:
1 import time import time2 from flask import Flask3 app = Flask(__name__)4 5 app.route('/line_test')6 def line_test():7 #土鱉方法8 first_time=time()9 for item in range(5):
10 time.sleep(1)
11 #土鱉方法
12 print time()-first_time
13 for item in xrange(5):
14 time.sleep(0.5)
15 #土鱉方法
16 print time()-first_time 方法缺點:需要大量時間編寫 關于 time()的代碼,最后還要刪除這些代碼,浪費時間
現在的解決方法:
使用python的 line_profiler 模塊,此模塊是用來測試 函數 每行代碼的響應時間等情況。
具體思路:將 line_profiler相關函數封裝在裝飾器 中 進行使用,這樣 在接口請求時,則會執行此裝飾器并打印出結果。
windows安裝方法:https://www.lfd.uci.edu/~gohlke/pythonlibs/#line_profiler??
代碼如下:
1 #coding:utf82 from flask import Flask, jsonify3 import time4 from functools import wraps5 from line_profiler import LineProfiler6 7 #查詢接口中每行代碼執行的時間8 def func_line_time(f):9 @wraps(f) 10 def decorator(*args, **kwargs): 11 func_return = f(*args, **kwargs) 12 lp = LineProfiler() 13 lp_wrap = lp(f) 14 lp_wrap(*args, **kwargs)
15 lp.print_stats()
16 return func_return
17 return decorator
18
19
20 app = Flask(__name__)
21
22 @app.route('/line_test')
23 @func_line_time
24 def line_test():
25 for item in range(5):
26 time.sleep(1)
27 for item in xrange(5):
28 time.sleep(0.5)
29 return jsonify({'code':200})
30
31 if __name__=='__main__':
32 app.run()
?
當瀏覽器請求接口時得到的結果如下:
* Running on http://127.0.0.1:5000/ Timer unit: 1e-06 s
Total time: 7.50827 s
File: /home/rgc/baidu_eye/carrier/test/flask_line_profiler_test.py
Function: line_test at line 22
Line # Hits Time Per Hit % Time Line Contents
22 @app.route(<span style="color: #800000;">'</span><span style="color: #800000;">/line_test</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span>23<span style="color: #000000;"> @func_line_time
</span>24 <span style="color: #0000ff;">def</span><span style="color: #000000;"> line_test():
</span>25 6 33.0 5.5 0.0 <span style="color: #0000ff;">for</span> item <span style="color: #0000ff;">in</span> range(5<span style="color: #000000;">):
</span>26 5 5005225.0 1001045.0 66.7 time.sleep(1<span style="color: #000000;">)
</span>27 6 31.0 5.2 0.0 <span style="color: #0000ff;">for</span> item <span style="color: #0000ff;">in</span> xrange(5<span style="color: #000000;">):
</span>28 5 2502696.0 500539.2 33.3 time.sleep(0.5<span style="color: #000000;">)
</span>29 1 282.0 282.0 0.0 <span style="color: #0000ff;">return</span> jsonify({<span style="color: #800000;">'</span><span style="color: #800000;">code</span><span style="color: #800000;">'</span>:200<span style="color: #000000;">})
127.0.0.1 - - [05/Mar/2018 15:58:21] “GET /line_test HTTP/1.1” 200 -
?
返回結果中 具體 含義:
?Total Time:測試代碼的總運行時間?
Line:代碼行號
Hits:表示每行代碼運行的次數 ?
Time:每行代碼運行的總時間 ?
Per Hits:每行代碼運行一次的時間 ?
% Time:每行代碼運行時間的百分比
?
?從 中便可看到 具體 26行代碼執行時間最長。
方法優點:只需要添加一個裝飾器,再接口函數前引用即可,刪除也容易,且 裝飾器可以重復使用,節省大量時間。
?
其他關于line_profiler的使用方法:
在腳本中使用此方法:
1 #coding:utf82 import cgi3 import time4 from line_profiler import LineProfiler5 6 def test2():7 print 'hello!test2()'8 9 def test1():
10 html='''<script>alert("you are a good boy!&I like you")</scrpit>'''
11 test2()
12 escape_html=cgi.escape(html)
13 for item in range(5):
14 time.sleep(1)
15 print escape_html
16
17 if __name__=='__main__':
18 lp=LineProfiler()
19 #同時顯示函數每行所用時間和調用函數每行所用時間,加入add_function()
20 lp.add_function(test2)
21 lp_wrap=lp(test1)
#如果被測函數有入參,下面一行為 lp_wrap(被測函數入參)
22 lp_wrap()
23 lp.print_stats()
?
?直接運行顯示結果:
* Running on http://127.0.0.1:5000/ Timer unit: 1e-06 s
Total time: 7.50827 s
File: /home/rgc/baidu_eye/carrier/test/flask_line_profiler_test.py
Function: line_test at line 22
Line # Hits Time Per Hit % Time Line Contents
22 @app.route(<span style="color: #800000;">'</span><span style="color: #800000;">/line_test</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span>23<span style="color: #000000;"> @func_line_time
</span>24 <span style="color: #0000ff;">def</span><span style="color: #000000;"> line_test():
</span>25 6 33.0 5.5 0.0 <span style="color: #0000ff;">for</span> item <span style="color: #0000ff;">in</span> range(5<span style="color: #000000;">):
</span>26 5 5005225.0 1001045.0 66.7 time.sleep(1<span style="color: #000000;">)
</span>27 6 31.0 5.2 0.0 <span style="color: #0000ff;">for</span> item <span style="color: #0000ff;">in</span> xrange(5<span style="color: #000000;">):
</span>28 5 2502696.0 500539.2 33.3 time.sleep(0.5<span style="color: #000000;">)
</span>29 1 282.0 282.0 0.0 <span style="color: #0000ff;">return</span> jsonify({<span style="color: #800000;">'</span><span style="color: #800000;">code</span><span style="color: #800000;">'</span>:200<span style="color: #000000;">})
127.0.0.1 - - [05/Mar/2018 15:58:21] “GET /line_test HTTP/1.1” 200 -
?相對于另一種使用方法:
1.在需要測試的函數前添加裝飾器 ?@profile
2.啟動程序 $kernprof -l -v test.py
無需 實際運行項目時刪除@profile,如需單獨測試此函數,直接使用 if __name__=='__main__': 即可,這樣在其他函數引用時,不會執行line_profiler相關代碼。
?
相關博客:
http://blog.csdn.net/guofangxiandaihua/article/details/77825524
標簽: line_profiler, python
<div id="blog_post_info">
好文要頂 關注我 收藏該文
RGC關注 - 0
粉絲 - 7 +加關注 0 0
<div class="clear"></div>
<div id="post_next_prev"><a href="https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_327days.html" class="p_n_p_prefix">? </a> 上一篇: <a href="https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_327days.html" title="發布于 2018-01-01 19:39">前端js,后臺python實現RSA非對稱加密</a>
<br>
<a href="https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_603days_1.html" class="p_n_p_prefix">? </a> 下一篇: <a href="https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_603days_1.html" title="發布于 2018-03-05 21:54">memory_profiler的使用</a>
posted on 2018-03-05 16:36?RGC 閱讀(2122) 評論(0) 編輯 收藏
加上之后多進程就編程單進程了 
總結
以上是生活随笔為你收集整理的line_profile逐行代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 正则语法完全正则表达式手册_语法格式重点
- 下一篇: python2转python3文件