用py-spy分析Python代码

如果你的python脚本执行很慢,有很多种方法对它的性能进行分析,比如cProfile就很好。

如果你想对正在运行的python进程进行性能分析,cProfile则无能为力,因为程序已经在运行,如果是生产环境,不可能为了配合你分析性能而重新启动程序。

Py-spy可以对正在运行的python进程进行分析,其原理是获取调用堆栈,在linux系统下,通过process_vm_readv,在mac下使用vm_read,在windows上使用ReadProcessMemory。

使用一段计算pi的程序来测试py-spy工具的使用,先安装

pip install py-spy

计算pi的程序如下

from __future__ import division


def get_pi(number):
    number1 = number+10
    b = 10**number1
    x1 = b*4//5
    x2 = b// -239
    he = x1+x2
    number *= 2

    for i in range(3, number,2):
        x1 //= -25
        x2 //= -57121
        x = (x1+x2) // i
        he += x

    pai = he*4
    pai //= 10**10
    paistring=str(pai)
    result = paistring[0]+str('.')+paistring[1:len(paistring)]
    print(result)

get_pi(1000000)

这段程序会运行一定时间,在运行期间,使用py-spy分析代码

1. dump py-spy dump

通过获取调用堆栈,可以了解程序内部的执行情况,了解函数之间的调用关系

[root@pyhost ~]# py-spy dump --pid 21512
Process 21512: python test.py
Python v2.7.5 (/usr/bin/python2.7)

Thread 21512 (idle)
    get_pi (test.py:15)
    <module> (test.py:25)

2. top

top 命令可以展示哪些函数被调用执行的次数最多,由于我测试的程序只有一个函数,因此只显示了一个函数。

从显示内容看,13,14,15这3行代码最耗费性能。

[root@pyhost ~]# py-spy top --pid 22135


Collecting samples from 'python test.py' (python v2.7.5)
Total Samples 800
GIL: 100.00%, Active: 100.00%, Threads: 1

  %Own   %Total  OwnTime  TotalTime  Function (filename:line)                                                                         
 36.00%  36.00%    3.06s     3.06s   get_pi (test.py:15)
 18.00%  18.00%    2.38s     2.38s   get_pi (test.py:14)
 40.00%  40.00%    2.32s     2.32s   get_pi (test.py:13)
  6.00%   6.00%   0.240s    0.240s   get_pi (test.py:16)
  0.00% 100.00%   0.000s     8.00s   <module> (test.py:25)

3. 火焰图

火焰图可以更加形象直观的展示进程内资源耗费情况

py-spy record -o profile.svg --pid 21512

生成的profile.svg文件可以在浏览器里查看,效果如下
py-spy
也可以直观的反应出13,14,15 这三行代码比较耗时。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案