Python(用pyinstrument做性能分析)
导引
【Python(用pyinstrument做性能分析)】在计算密集型计算或一些Web应用中,我们常常需要对代码做性能分析。在Python中,最原始的方法即是使用time
包中的time
函数(该函数以秒为计时单位):
from time import sleep, timedef func1():
sleep(0.001)def func2():
sleep(2)begin1 = time()
func1()
end1 = time()begin2 = time()
func2()
end2 = time()
print("func1 consume: %f, func2 consume:%f, func3 consume: %f"\
% (end1-begin1, end2-begin2, end2-begin1))
控制台输出如下:
func1 consume: 0.001271, func2 consume:2.000421, func3 consume: 2.001692
pyinstrument基本用法 但是一旦函数多了起来,这种方式显然过于繁杂。类似C语言中的cProfile,在Python中,也有专门的性能分析工具
pyinstrument
(该库非内置,需要使用conda/pip安装),我们在复杂的项目中可以使用它来代替简陋的time.time()
。首先来看一下基本的使用,它的使用框架如下:
from pyinstrument import Profiler
from time import sleepdef func1():
sleep(0.1)def func2():
sleep(2)profiler = Profiler()
profiler.start()# 这里是你要分析的代码,我们这里分析func1和func2两个函数
func1()
func2()profiler.stop()profiler.print()
可以看到,该工具也将其成功分析出了个函数的运行时间,并为我们标红指出了运行2s的func2函数是性能瓶颈:
文章图片
如果我们进一步调低函数的运行时间:
def func3():
sleep(0.0001)profiler = Profiler()
profiler.start()func3()profiler.stop()profiler.print()
此时会显示“No samples were recorded”,如下:
文章图片
这是因为你的代码运行时间小于了1ms,如果你仍然想分析这段代码,你可以选择将间隔值调到比默认的0.001(1ms)小,比如这样:
profiler = Profiler(interval=0.0001)
此时你会发现,func3也能被检测出来了:
文章图片
此外,如果你要在浏览器中查看分析结果,可以使用
profiler.open_in_browser()
代替profiler.print()
的控制台打印输出:文章图片
也可以使用
profiler.output_html()
将profile以html形式输出。分析Flask中的web响应性能 我们也可以对Flask应用进行性能分析,具体的用法如下:
from flask import Flask, g, make_response, request
app = Flask(__name__)@app.before_request
def before_request():
if "profile" in request.args:
g.profiler = Profiler()
g.profiler.start()@app.after_request
def after_request(response):
if not hasattr(g, "profiler"):
return response
g.profiler.stop()
output_html = g.profiler.output_html()
return make_response(output_html)
这样程序会检测每个request中的
?profile
参数,如果检测到则会开始分析。在运行了profiler的request结束后,它会生成一个html输出替代掉真实的response并返回。参考
- [1] https://docs.python.org/3/library/time.html?highlight=time#time.time
- [2] https://pyinstrument.readthedocs.io/en/latest/guide.html
推荐阅读
- mysql之常用函数(核心总结)
- 打印总是遇到问题(一文教你如何在优麒麟上使用 CUPS 管理打印机)
- Java的jstack命令使用详解
- java线程池使用及原理面试题
- 如何在|如何在 K3s 中启用 Traefik Dashborad
- 产品手册怎么做?用什么软件?
- 如何在Spark Scala/Java应用中调用Python脚本
- 论如何在使用RedisStandaloneConfiguration时让JedisConnectionFactory用上JedisPoolConfig
- 数据结构和算法基于python语言_数据结构与算法(Python语言描述)
- Python系列|数据结构与算法笔记(五)——队列(FIFO队列、双端队列)