python函数调用关系分析
在Pycharm的专业版中,提供了一个分析项目性能的工具run->Profile
,可以将工程运行时各函数的调用次数和所用时间记录下来,提供静态数据和关系图表两种表达方式。
只需轻轻一点,统计数据和图表关系一览无遗,确实方便。但是此方法局限性很大,一是必须使用pycharm,这样使用其他ide如VS Code的用户就没法使用了;二是它不仅要使用pychram,还得是专业版,专业版是要收费的(破解和学生版除外),这又是一道坎挡在了我们的路上。那么有其他的方法来进行类似的分析吗?当然是有的。
profile
profile可以分析函数运行时的性能消耗情况,调用方法如下:
1 | import profile |
main()即为需要分析的入口函数,以字符串形式传入。运行之后可以得到如下的输出:
1 | 19 function calls in 0.000 seconds |
虽然函数调用情况可以得到的,但是分析起来比较麻烦,函数之间的调用关系也没有给出。此方式虽然简单但是不够直观。
pycallgraph
在pycallgraph之前不得不先提及一下Graphviz,毕竟pycallgraph是基于Graphviz的。Graphviz是开源的图形可视化软件,能够将结构信息表示为抽象图和网络图的方法。至官网下载并安装Graphviz:http://www.graphviz.org/download/,同时在将graphviz\bin
添加到环境变量中。graphviz中有多种布局器,pycallgraph所使用的便是其中的dot.
1 | dot 默认布局方式,主要用于有向图 |
看看graphviz都能画些什么样的图:
安装并配置好graphviz后,需要安装pycallgraph,直接使用pip安装即可:
1 | pip install pycallgraph |
之后可以通过命令行或代码来生成函数调用关系图。
命令行(windows中不识别pycallgraph,应该还要需要配置其环境变量):
1 | pycallgraph graphviz -- ./main.py |
code:
1 | from pycallgraph import PyCallGraph |
当然可以配置显示或不显示哪些函数:
1 | from pycallgraph import Config |
运行后再当前目录下生成test.png文件绘制了函数调用关系(默认文件名是pycallgraph.png):
1 | class GraphvizOutput(Output): |
可见此方式对函数的调用关系展示得较为清晰明了,其缺点是制作的图分辨率不高,略显模糊。下为yolov5的调用关系图。
cProfile+snakeviz
使用cProfie可以将函数运行分析结果保存为.prof文件,然后使用其他工具进行可视化,此处以snakeviz为例。
cProfile
使用cProfile分析工程,可以使用命令行和代码两种方式。
- cmd
1 | python -m cProfile -o result.prof test.py |
- code
1 | import cProfile |
不推荐使用命令行形式,针对,整个文件,会打包过多的无用函数,影响观感。使用code方式针对特定函数分析即可。
snakeviz
安装snakeviz:
1 | pip install snakeviz |
直接调用cProfile生成的文件,在浏览器中可以打开交互式网页,查看分析结果。缺点:虽然能够从图中获知函数调用顺序,但是函数调用关系依旧不够直观。