前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[python][profiling]python的性能监控的几种方法

[python][profiling]python的性能监控的几种方法

作者头像
皮振伟
发布2018-10-10 11:36:42
1.7K0
发布2018-10-10 11:36:42
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏

前言: 编译型语言,比如C,C++,Go编译出来的二进制,可以使用perf来分析性能。对于编译出来的elf格式,使用dwarf来分析symbol。 对于python这种解释型语言,就会比较麻烦。因为python进程的stack是Cpython的stack,并非对应的py的stack。 分析: 1,cProfile python的官方提供了profiling工具,https://docs.python.org/2/library/profile.html 用法上,需要修改代码,重新执行。对于线上业务,其实是不太友好的。另外就是如果父进程启动之后,启动子进程执行,就没法工作了。 相比这种方式,作者更倾向旁路的方式,对于一个running的python进程进行profiling,业务进程不需要修改,也无感知(允许一定范围内的性能下降)。像perf一样,不侵入进程的情况下进行性能分析,用起来更舒服一些。 2,cpython的stack 来一段测试代码:

打印的结果是:

python的内置的traceback的结果,也是我们预期的。 实际上,使用gdb得到的结果:

可见,python进程的stack,是解释器的二进制的stack。 3,py-bt python提供了gdb的能力,但是对gdb的版本有些要求。搭起来环境,发现gdb可以dump出来python的backtrace。 順藤摸瓜,分析libpython.py的代码发现: a,使用gdb来dump出来cpython的stack b,过滤掉非python的stack,方法就是判断frame的名字是不是“PyEval_EvalFrameEx”

c,在python的frame中保存了line number和file name。解释出来frame即可。 可见,gdb提供了一个很好的例子,使用旁路的方法,可以获取到python的backtrace。 那么,我们可以使用另外一个进程,每秒抓取1000次backtrace,哪个backtrace命中的更多,就说明CPU更加密集。好吧,这个动作的准确名词是“采样”,当然采样的频率可以调整才是。 4,pstack pstack和gdb的原理类似,都是使用kernel提供的ptrace这个syscall实现的。 相比于gdb,pstack更加合适。实际上,目前upstream上已经开始支持了python的trace。 改造pstack是一个不错的方法。 5,pyflame uber开源了pyflame工具,https://github.com/uber/pyflame 也是完全的旁路profiling工具。目前支持的功能基本满足需求,可以分析出来各个backtrace的命中次数,结合flame graph画出热点图。 值得一说的是,pyflame的实现上,和gdb的方式有很大差别: a,在cpython中,_PyThreadState_Current这个symbol保存着当前正在运行的thread。 b,在_PyThreadState_Current中保存着当前python栈的frame。 c,从当前的frame信息中得到行号和文件名,以及上一级frame的指针。 d,遍历frame得到所有的backtrace。 综上,pyflame是一个不错的旁路profiling工具。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档