使用line_profiler查看api接口函数每行代码执行时间

使用line_profiler查看api接口函数每行代码执行时间

大家好,又见面了,我是全栈君。

项目情景描述

  在restful架构风格的项目交付测试的过程中,某接口出现 请求超时导致的http 502 Bad Gateway,于是开始排查具体是接口函数中的哪行代码或函数 响应时间过长导致的502错误

刚开始的解决方法:

  土鳖式的导入 time模块进行时间计算,从而查出具体响应时间过长的位置

  如下:

 1 import time import time
 2 from flask import Flask
 3 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:utf8
 2 from flask import Flask, jsonify
 3 import time
 4 from functools import wraps
 5 from line_profiler import LineProfiler
 6 
 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('/line_test')
    23                                           @func_line_time
    24                                           def line_test():
    25         6         33.0      5.5      0.0      for item in range(5):
    26         5    5005225.0 1001045.0     66.7          time.sleep(1)
    27         6         31.0      5.2      0.0      for item in xrange(5):
    28         5    2502696.0 500539.2     33.3          time.sleep(0.5)
    29         1        282.0    282.0      0.0      return jsonify({
   
   'code':200})

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:utf8
 2 import cgi
 3 import time
 4 from line_profiler import LineProfiler
 5 
 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('/line_test')
    23                                           @func_line_time
    24                                           def line_test():
    25         6         33.0      5.5      0.0      for item in range(5):
    26         5    5005225.0 1001045.0     66.7          time.sleep(1)
    27         6         31.0      5.2      0.0      for item in xrange(5):
    28         5    2502696.0 500539.2     33.3          time.sleep(0.5)
    29         1        282.0    282.0      0.0      return jsonify({
   
   'code':200})

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

  

转载于:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_603days.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107681.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • iic通信协议是什么[通俗易懂]

    iic通信协议是什么[通俗易懂] iic通信协议是什么  IIC协议是二线制,信号线包含SDA和SCL,且信号线是双向的,开路结构,需要通过上拉电阻到VCC,具体的电阻值影响的是信号反应速度和驱动能力。  首先,IIC通信与UART,还有SPI统称为串行接口通信,不过它们之间还是有区别的,如UART的负电平逻辑,还有UART通信不需要时钟,只需要特定的波特率即可,SPI与IIC都可以有一个主机,多个从机的情况,…

    2022年6月9日
    49
  • 【Android Tricks 6】ViewPager首页与尾页的滑动动作响应[通俗易懂]

    【Android Tricks 6】ViewPager首页与尾页的滑动动作响应

    2022年1月28日
    46
  • Redis缓存穿透、缓存雪崩问题分析

    Redis缓存穿透、缓存雪崩问题分析把redis作为缓存使用已经是司空见惯,但是使用redis后也可能会碰到一系列的问题,尤其是数据量很大的时候,经典的几个问题如下:(一)缓存和数据库间数据一致性问题分布式环境下(单机就不用说了)非常容易出现缓存和数据库间的数据一致性问题,针对这一点的话,只能说,如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存。我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两…

    2022年6月29日
    27
  • jquery正则表达式验证邮箱_正则表达式如何判断邮箱

    jquery正则表达式验证邮箱_正则表达式如何判断邮箱我的代码一开始如下:然后我的表单就一直没法成功调用这个函数,后面我发现,这里的跟java的不一样,reg里的正则表达式必须得用’/’,双引号赋值它不识别,还有下面调用test函数,上面if语句里面验证邮箱是否正确,用的email.test(reg),它打开网页还是没有提示。得像下面这个才能正常调用test。…

    2022年9月20日
    2
  • visual studio创建数据库_读取硬件安装信息

    visual studio创建数据库_读取硬件安装信息管理类是WMI类,如Win32_LogicalDisk,,该类型可表示一个磁盘驱动器,并Win32_Process,,它表示的进程Notepad.exe等。在.NET的项目中,有时候需要获取计算机的硬件的相关信息,在C#语言中需要利用ManagementClass这个类来进行相关操作。以上是对ManagementClass类的部分谁明,此类型的所有公共静态成员都是线程安全的。以上的获取硬件信息的方法可以直接封装在一个类中,可以在项目中直接引用,这样可以加快项目的开发速度。…

    2022年10月2日
    3
  • mysql实战34讲_有效教学十讲读书心得

    mysql实战34讲_有效教学十讲读书心得此文为极客时间:MySQL实战45讲的4、5、9、10、11、15、18节索引相关部分的总结一、Innodb索引模型1.主键/非主键索引的区别每个索引在Innodb中都是一颗B+树,其中根据索

    2022年8月16日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号