火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的,和所有其他的 profiling 方法不同的是,火焰图以一个全局的视野来看待时间分布,它从底部往顶部,列出所有可能导致性能瓶颈的调用栈。

 

strace命令 是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。当然strace与专业的调试工具比如说gdb之类的是没法相比的,因为它不是一个专业的调试器。

yum install perf
perf record -F 999 -a -g -- sleep 10
perf record -F 999 -p 834 -g -- sleep 20
-F: 采样频率
-a: 所有程序
-g: 记录函数间的调用关系
-p: 待分析进程的id


https://github.com/brendangregg/FlameGraph下载FlameGraph 解压  然后进入FlameGraph目录

perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > out.svg    生成火焰图

sz out.svg

 python 优化

 cProfile 有多种调用方法,可以直接从命令行调用:

python -m cProfile -s tottime your_program.py

其中的 -s 的意思是 sort。常用的 sort 类型有两个:

  1. tottime,指的是函数本身的运行时间,扣除了子函数的运行时间
  2. cumtime,指的是函数的累计运行时间,包含了子函数的运行时间

要获得对程序性能的全面理解,经常需要两个指标都看一下。

不过在这里,我们并不能直接使用命令行方式调用,因为我的代码中还需要一些比较繁重的配置加载,如果把这部分时间算进去了,多少有些干扰,那么我们也可以直接在代码中调用 cProfile。

使用 cProfile 的代码如下:

import cProfile
import io
import pstats


def on_start():
    '''
    需要测试的代码
    '''
    pass


pr = cProfile.Profile()
pr.enable()  # 开始收集性能分析数据

on_start()  # 需要测试的代码
pr.disable()  # 停止收集性能分析数据

s = io.StringIO()
sortby = "cumtime"  # 仅适用于 3.6, 3.7 把这里改成常量了
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)   # 打印数据
# pr.dump_stats(r"requests.prof")  # 把当前性能分析的内容写入一个文件
ps.print_stats()
print(s.getvalue())

 下一步我们开始使用火焰图,可视化往往能让我们更容易注视到性能瓶颈

import cProfile
import io
import pstats


def on_start():
    '''
    需要测试的代码
    '''
    pass


pr = cProfile.Profile()
pr.enable()  # 开始收集性能分析数据

on_start()  # 需要测试的代码
pr.disable()  # 停止收集性能分析数据

s = io.StringIO()
# sortby = "cumtime"  # 仅适用于 3.6, 3.7 把这里改成常量了
# ps = pstats.Stats(pr, stream=s).sort_stats(sortby)   # 打印数据
pr.dump_stats(r"requests.prof")  # 把当前性能分析的内容写入一个文件
# ps.print_stats()
# print(s.getvalue())

执行完在当前目录下会生成一个requests.prof文件

pip3.8 install flameprof

flameprof requests.prof > requests.svg  # 转为可视化图

会生成requests.svg使用浏览器打开