pstats --- 性能分析器的统计信息

源代码: Lib/pstats.py


pstats 模块提供了用于读取、操纵和显示由 Python 的性能分析器生成的性能分析统计信息。 它能够读取来自 profiling.tracing (确定型性能分析器) 和 profiling.sampling (统计型性能分析器) 的输出。

读取和显示性能分析数据

Stats 类是用于处理性能分析数据的主要接口。 它可以读取来自文件或者直接来自 Profile 对象的统计信息。

加载来自文件的统计信息并打印基础报告:

import pstats

p = pstats.Stats('profile_output.prof')
p.print_stats()

Stats 对象提供了在打印之前对数据进行排序和过滤的方法。 举例来说,如果要查看累积时间最多的十个函数:

from pstats import SortKey

p = pstats.Stats('profile_output.prof')
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)

使用统计数据

Stats 类支持方法链式调用,从而便于执行多个操作:

p = pstats.Stats('restats')
p.strip_dirs().sort_stats(-1).print_stats()

strip_dirs() 方法会从文件名中移除目录路径,使输出更加简洁;sort_stats() 方法则接受多种键来控制排序顺序。

不同的排序键会突出显示性能的不同方面:

from pstats import SortKey

# Functions that consume the most cumulative time
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)

# Functions that consume the most time in their own code
p.sort_stats(SortKey.TIME).print_stats(10)

# Functions sorted by name
p.sort_stats(SortKey.NAME).print_stats()

过滤输出

print_stats() 方法接受限制条件,用于筛选要显示的函数。限制条件可以是整数(用于限制数量)、0 到 1 之间的浮点数(用于选择百分比),或字符串(通过正则表达式匹配函数名称)。

仅打印排名前 10% 的结果:

p.print_stats(.1)

仅打印名称中包含“init”的函数:

p.print_stats('init')

Combine restrictions (they apply sequentially):

# Top 10%, then only those containing "init"
p.print_stats(.1, 'init')

# Functions in files matching "foo:", limited to top 50%
p.sort_stats(SortKey.FILENAME).print_stats('foo:', .5)

分析调用关系

print_callers() 方法会显示调用每个已显示函数的具体函数:

p.print_callers()

print_callees() 方法则呈现相反的关系,列出每个已显示函数所调用的函数:

p.print_callees()

两种方法接受的限制参数与 print_stats() 相同。

组合多个配置文件

可将多次性能分析运行的统计数据合并到单个 Stats 对象中:

# Load multiple files at once
p = pstats.Stats('run1.prof', 'run2.prof', 'run3.prof')

# Or add files incrementally
p = pstats.Stats('run1.prof')
p.add('run2.prof')
p.add('run3.prof')

当文件被合并时,相同函数(相同的文件、行和名称)的统计数据会被汇总,从而形成所有性能分析运行结果的聚合视图。

Stats 类

class pstats.Stats(*filenames_or_profile, stream=sys.stdout)

根据配置文件数据创建统计对象。

这些参数可以是文件名(字符串或类路径对象),也可以是 Profile 对象。如果提供了多个来源,则会将它们的统计信息合并。

stream 参数用于指定将来自 print_stats() 及相关方法的输出写入何处。其默认值为 sys.stdout。

配置文件数据格式取决于创建该格式的 Python 版本。Python 版本之间或不同分析器之间不提供兼容性保证。

strip_dirs()

从所有文件名中移除前导路径信息。

该方法会在原地修改对象,并将其返回以供方法链式调用。经过剥离后,统计数据将被视为处于随机顺序。

如果剥离导致两个函数变得无法区分(具有相同的文件名、行号和函数名),则它们的统计信息将被合并为一条记录。

add(*filenames)

从其他文件中添加性能分析数据。

这些文件必须由同一种类型的 Profiler 创建;相同函数的统计数据会被累加。

dump_stats(filename)

将当前统计数据保存至文件中。

如果文件不存在,则将其创建;如果文件已存在,则将其覆盖。保存的数据可通过创建一个新的 Stats 对象来加载。

sort_stats(*keys)

根据指定的条件对统计数据进行排序。

每个键可以是字符串或 SortKey 枚举成员。当提供多个键时,后出现的键会在与先前键值相等的情况下优先胜出。

使用 SortKey 枚举成员比使用字符串更为推荐,因为前者能提供更好的错误检查:

from pstats import SortKey
p.sort_stats(SortKey.CUMULATIVE)

有效的排序键:

字符串

枚举

含义

'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

内部时间

各类统计排序均按降序排列(耗时最长的项排在最前面);而名称、文件名和行号排序则按升序(字母顺序)排列。

SortKey.NFL 与 SortKey.STDNAME 的区别在于:NFL 按数字顺序对行号进行排序,而 SortKey.STDNAME 则按字符串顺序进行排序。sort_stats(SortKey.NFL) 与 sort_stats(SortKey.NAME, SortKey.FILENAME, SortKey.LINE) 等价。

出于向后兼容考虑,数值参数 -1、0、1 和 2 同样被接受,即分别对应 'stdname'、'calls'、'time' 和 'cumulative'。

在 3.7 版本加入: SortKey 枚举。

reverse_order()

反转当前的排序顺序。

默认情况下,排序方向会根据排序键自动选择(基于时间的键采用降序,基于名称的键采用升序)。本方法会反转这一选择。

print_stats(*restrictions)

打印一份性能分析统计报告。

输出内容包括一条汇总数据的标题行,随后是一个按最后一次 sort_stats() 调用排序的函数统计表。

限制条件会对输出进行过滤。每个限制条件要么为:

  • 整数:将输出限制为该数量条目

  • 一个介于 0.0 和 1.0 之间的浮点数:用于选择相应比例的条目

  • 字符串:通过正则表达式匹配函数名

限制条件按顺序依次应用。例如:

print_stats(.1, 'foo:')

首先对前 10% 进行限制,然后筛选出与 ‘foo:’ 匹配的函数。

print_callers(*restrictions)

将统计结果中每个函数的调用情况打印出来。

对于过滤结果中的每个函数,会显示调用该函数的函数及其调用次数。

对于 profiling.tracing (或 cProfile),每条调用线路会显示三个数值:来自该调用者的调用次数,以及这些特定调用的总次数和累计次数。

接受与 print_stats() 相同的限制参数。

print_callees(*restrictions)

打印统计量中每个函数所调用的函数。

这是 print_callers() 的逆过程,用于显示每个列出的函数调用了哪些函数。

接受与 print_stats() 相同的限制参数。

get_stats_profile()

返回一个包含统计信息的 StatsProfile 对象。

返回的对象提供了对配置文件数据的程序化访问权限;其中,函数名称被映射到包含计时信息和调用次数信息的 FunctionProfile 对象。

在 3.9 版本加入.

class pstats.SortKey

Stats.sort_stats() 的有效排序键枚举列表。

CALLS

按调用次数排序。

CUMULATIVE

按累计时间排序。

FILENAME

按文件名排序。

LINE

按行号排序。

NAME

按函数名称排序。

NFL

按名称排序,随后按文件排序,再按行号排序(数字行号排序)。

PCALLS

按原始(非递归)调用次数排序。

STDNAME

按标准名称排序(基于字符串的行排序)。

TIME

按内部时间排序(函数内时间,不包括子调用时间)。

命令行接口

pstats 模块可作为脚本调用,以交互式方式浏览配置文件数据:

python -m pstats profile_output.prof

这将打开一个以行为导向的界面(基于 cmd 构建),用于查看统计信息。在提示符处输入 help,以查看可用命令。

参见

profiling

Python 性能分析工具概述。

profiling.tracing

确定性追踪性能分析器。

profiling.sampling

统计抽样分析器。