Python性能分析实战1
前置知识
- Python基础语法
- cProfile基本使用
问题
环境上发现有接口请求的响应时间高达10s以上,严重影响功能的使用
需要分析具体的代码执行耗时,针对问题代码进行优化,优化接口性能
解决思路
分析代码执行情况
使用 cProfile 工具,将目标接口的代码执行情况dump到文件中
1 |
|
获得dump文件后,使用 snakeviz 渲染方便查看
1 |
|
执行命令后,snakeviz 会自动打开浏览器显示渲染后的结果

可以看到接口中调用的service方法耗时长达10s左右,根据图示的调用栈可以看到耗时久主要是跟一个decrypt方法有关
接下来到底下的搜索框过滤出关于decrypt相关的执行情况

可以看到,decrypt相关的方法被调用37次,每次耗时0.2s左右
0.2s算是比较耗时的操作了,这样耗时的代码逻辑居然还执行了37次,最终导致总耗时有7s之多
分析问题代码
找到了可能有问题的代码位置,接下来就要看看对应的代码逻辑了
本文中代码涉及私密信息,仅以伪代码的方式进行讲解
decrypt实际上是一个解密的方法,解密算法需要进行大量的运算,这也解释了为什么这个操作单次就需要耗费0.2s了
为什么需要这个解密操作
这里实际上是对需要连接的中间件密码进行解密
伪代码如下:
1 |
|
生产环境中的密码都是经过加密处理的,所以这里需要解密的操作
那么就是说这个操作不可避免,也没有很大优化空间了
这里就有个疑问了,既然只是一个密码解密的操作,且只是一个配置类,为什么需要调用那么多次,只需要在服务启动之时进行一次初始化的操作就可以了
尝试修复
根据查看代码逻辑后分析的原因,尝试将解密的操作放到初始化的流程中,并使用functools.cached_property缓存计算结果(这样就可以保证只进行一次计算,后续直接从缓存获取结果)
伪代码如下:
1 |
|
还没结束?
代码修改后再次dump查看优化结果

看起来优化的效果还是很明显的,但是接口仍然有2s的耗时,没有达到预期的效果
分析耗时主要是在service中一个查询instance的方法,通过id查询 Mongo
这里查询数据的操作就耗费了2s
这里按道理如果这是个单独的一次查询,2s已经属于慢查询了,但是并没有接到慢查询的告警消息
可以先猜测下原因