使用 Python 的 cProfile 模块分析代码性能

cProfile 模块是自 python 2.5 以来标准版 Python 解释器的默认性能分析器。它是一种确定性分析器,只测量 CPU 时间,并不包含内存消耗和其他与内存相关联的信息。
代码分析模板如下:

import cProfile, pstats, io
from pstats import SortKey
pr = cProfile.Profile()
pr.enable()
# ... do something ...
pr.disable()
s = io.StringIO()
sortby = SortKey.CUMULATIVE
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())

我们在 do something 所在行内,编写需要性能测试的代码。

输出结果形如:

具体步骤如下:

  1. 首先导入相关模块。
  2. 初建 Profile 对象。
  3. 初建 IO 对象,用于存储分析结果。
  4. 设定分析结果排序字段。
  5. 开始分析。
  6. 打印分析结果。

统计结果字段说明如下:

字段 说明
ncalls 调用次数。
tottime 在指定函数中消耗的总时间(不包括调用子函数的时间)。
percall tottime 除以 ncalls 的商,即平均时间。
filename:lineno(function) 详情说明,即调用函数所在文件名:行号(函数名)。

用到了 cProfile 对象中的这些方法:

方法 说明
enable() 开始收集分析数据。
disable() 停止收集分析数据。
print_stats(sort=-1) 打印分析结果到输出流,默认为随机排序序列。

如果第一列中有两个数字(例如3/1),则表示函数递归。第二个值是原始调用次数,第一个是调用的总次数。注意,当函数不递归时,这两个值是相同的,并且只打印单个数字。

pstats.Stats 是个类,定义为:

 pstats.Stats(*filenames or profile, stream=sys.stdout)

用于创建统计对象,接受两个入参,代码示例中为 profile 和输出流。

pstats.Stats 有一个 sort_stats(*keys) 方法,用于排序统计结果,支持以下排序参数:

排序参数 有效枚举参数 含义
‘calls’ SortKey.CALLS 调用次数
‘cumulative’ SortKey.CUMULATIVE 累积时间
‘cumtime’ N/A 累积时间
‘file’ N/A 文件名
‘filename’ SortKey.FILENAME 文件名
‘module’ N/A 文件名
‘ncalls’ N/A 调用次数
‘pcalls’ SortKey.PCALLS 原始调用计数
‘line’ SortKey.LINE 行号
‘name’ SortKey.NAME 函数名称
‘nfl’ SortKey.NFL 名称/文件/行
‘stdname’ SortKey.STDNAME 标准名称
‘time’ SortKey.TIME 内部时间
‘tottime’ N/A 内部时间

发表评论