使用Profilers来分析Python程序的性能瓶颈

profile分析器简介

cProfile 和 profile 提供了 Python 程序的 确定性性能分析 。 profile 是一组统计数据,描述程序的各个部分执行的频率和时间。这些统计数据可以通过 pstats 模块格式化为报表。

Python 标准库提供了同一分析接口的两种不同实现:

  • 对于大多数用户,建议使用 cProfile ;这是一个 C 扩展插件,因为其合理的运行开销,所以适合于分析长时间运行的程序。该插件基于 lsprof ,由 Brett Rosen 和 Ted Chaotter 贡献。
  • profile 是一个纯 Python 模块(cProfile 就是模拟其接口的 C 语言实现),但它会显著增加配置程序的开销。如果你正在尝试以某种方式扩展分析器,则使用此模块可能会更容易完成任务。该模块最初由 Jim Roskind 设计和编写。

注解

profiler 分析器模块被设计为给指定的程序提供执行概要文件,而不是用于基准测试目的( timeit 才是用于此目标的,它能获得合理准确的结果)。这特别适用于将 Python 代码与 C 代码进行基准测试:分析器为Python 代码引入开销,但不会为 C级别的函数引入开销,因此 C 代码似乎比任何Python 代码都更快。

实时用户手册

本节是为 “不想阅读手册” 的用户提供的。它提供了非常简短的概述,并允许用户快速对现有应用程序执行评测。

要分析采用单个参数的函数,可以执行以下操作:

(如果 cProfile 在您的系统上不可用,请使用 profile 。)

上述操作将运行 re.compile() 并打印分析结果,如下所示:

第一行显示监听了197个调用。

在这些调用中,有192个是 原始的 ,这意味着调用不是通过递归引发的。

下一行: Ordered by: standard name ,表示最右边列中的文本字符串用于对输出进行排序。

列标题包括:

名称介绍
ncalls调用次数
tottime在指定函数中消耗的总时间(不包括调用子函数的时间)
percall是 tottime 除以 ncalls 的商
cumtime指定的函数及其所有子函数(从调用到退出)消耗的累积时间。这个数字对于递归函数来说是准确的
percall是 cumtime 除以原始调用(次数)的商(即:函数运行一次的平均时间)
filename:lineno(function)提供相应数据的每个函数

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

profile 运行结束时,打印输出不是必须的。也可以通过为 run() 函数指定文件名,将结果保存到文件中:

pstats.Stats 类从文件中读取 profile 结果,并以各种方式对其进行格式化。

cProfile 和 profile 文件也可以作为脚本调用,以分析另一个脚本。例如:

  • -o 将profile 结果写入文件而不是标准输出
  • -s 指定 sort_stats() 排序值之一以对输出进行排序。这仅适用于未提供 -o 的情况
  • -m 指定要分析的是模块而不是脚本。3.7 新版功能: cProfile 添加 -m 选项,3.8 新版功能: profile 添加 -m 选项

本文为原创文章,未经授权禁止转载本站文章。
原文出处:兰玉磊的个人博客
原文链接:https://www.fdevops.com/2021/03/17/profile-28077
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注