Python程序性能分析

  虽然不是所有的Python程序都需要严格的性能分析,不过知道如何利用Python生态圈里的工具来分析性能,也是不错的。

IDE集成的工具

我们可以使用Pycharm来进行Python性能的分析,在Pycharm顶部,Run -> Profile你的项目 运行。这个时候项目就会以性能分析的方式运行。你继续在项目中进行操作。最后会出现一个XXX.pstat的文件。其中就有相关的性能数据了。缺点是只能看见相关函数所占的时间不会具体到某行代码。但是支持快速跳转等功能。

line_profiler

Github链接:line_profiler
使用:

  1. 在要测试的方法前面加上@Profile装饰器

    1
    2
    3
    @profile
    def slow_function(a, b, c):
    ...
  2. 当是要测试的是某个脚本的时候

    1
    kernprof -l test.py
  3. 在Web项目(或其他项目)中运行的时候,Tornado为例

    1
    kernprof -l main.py 8050 #main.py是程序入口,端口可以不设置

    这么做目的是为了防止报出找到不包的问题。不管是哪种情况,都会生成一个脚本名.lprof的文件,里面存储的是二进制信息,我们可以使用 python -m line_profiler 脚本名.lprof 来进行分析

    1
    python -m line_profiler 脚本名.lprof

其他

在 flask 中使用的时候需要在 app.run 中加上参数 use_reloader=False,例:

1
app.run("127.0.0.1", "8080", use_reloader=False)

我们在使用的过程中,需要在函数上加上装饰器 @profile 但是加上后项目就不能正常的启动(除非进行性能分析),所以为了达到不报错的目的,我们将判断有没有 profile ,没有则创建一个空的函数(装饰器),python 3 中代码如下:

1
2
3
4
5
6
try:
import builtins
profile = builtins.__dict__['profile']
except KeyError:
# No line profiler, provide a pass-through version
def profile(func): return func

使用的时候,将上面代码写入lineProfile.py 中,并在要用到的地方导入,如下:

1
2
3
4
5
6
7
8
from tools.lineProfile import *

class User:
@staticmethod
@profile
def get():
pass
return {}

这样就达到了@profile 可以一直存在的目的,不管是性能分析还是正常的运行

line_profiler + memory-profiler

只需要加上 @profile 装饰器,就能实现既能测试花费的时间,也能测试消耗的内存

1
2
3
4
5
6
7
8
9
10
11
消耗时间测试:
1. pip install line-profiler
2. 在相关函数(方法)上加上@profile装饰器
3. 使用 kernprof -l server.py 启动 flask server(其他server 启动方法类似)。执行该命令后会生成一个内容为二进制的测试报告文件 【注意: 如果启动的为 flask 项目,须在 app.run 中 新增参数 use_reloader=False】
4. 查看性能测试报告 python -m line_profiler + 报告名称。例如 python -m line_profiler server.py.lprof
5. 当不对整个flask项目进行测试,只针对某个脚本进行测试时,可用 kernprof -l 脚本名 生成测报告文件,同样使用 python -m line_profiler + 报告名称 查看性能报告

内存使用测试:
1. pip install memory-profiler
2. 在相关函数(方法)上加上@profile装饰器
3. python -m memory_profiler server.py >> memory_result.txt