登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  python教程

Python pstats 怎样同时限制性能报告的排序和显示条目

来源:17golang原创

时间:2026-10-29 18:29:07 499浏览 收藏

如果你已经拿到一份 profile 数据,却发现报告太长,通常不需要重新采集。pstats.Stats 把“按什么顺序看”和“显示多少条”拆成了两个动作:先用 sort_stats() 选择排序键,再用 print_stats() 传入数量、比例或函数名限制。两者可以直接链式调用。

官方地址:https://docs.python.org/3/library/pstats.html

最常用的写法是 pstats.Stats('profile.prof').sort_stats(SortKey.CUMULATIVE).print_stats(10):按累计耗时排序,再打印前 10 条。若还要按函数名筛选,就继续给 print_stats() 传限制参数。

排序和显示条目分别由谁控制

sort_stats() 决定报告表格的排序方式,print_stats() 决定这次输出保留哪些条目。不要把 print_stats(10) 理解成“重新计算前十名”;它只是从当前排序结果中限制输出。

pstats 统计对象连接排序选择和显示限制的静态结构说明图
图1:结构说明图,查看 pstats 的排序选择与报告限制分别落在哪个对象和方法上。

例如,想优先查看累计耗时最高的函数,可以这样写:

import pstats
from pstats import SortKey

# 读取已有的性能统计文件。
stats = pstats.Stats("profile.prof")

# 累计耗时决定排序,10 决定本次报告最多显示多少条。
stats.sort_stats(SortKey.CUMULATIVE).print_stats(10)

如果关心函数自身消耗的时间,把排序键换成 SortKey.TIME;如果需要多级排序,可以传入多个键,后面的键用于打破前面排序键相同的情况。

数量、比例和函数名可以怎样限制

print_stats() 的限制参数有三类:整数表示最多保留多少条,0 到 1 之间的浮点数表示保留数据集的一部分,字符串则按函数名做正则匹配。它们都只影响显示,不会改变 profile 文件本身。

from pstats import SortKey

# 先按自身耗时排序,再只显示前 10 条。
stats.sort_stats(SortKey.TIME).print_stats(10)

# 只查看排序结果中的前 10%,适合先观察整体热点。
stats.sort_stats(SortKey.CUMULATIVE).print_stats(0.1)

# 只显示函数名匹配 init 的条目;字符串按正则处理。
stats.sort_stats(SortKey.NAME).print_stats("init")

一个常见误区是把整数当成筛选条件。print_stats(10) 不是“找出所有调用次数等于 10 的函数”,而是把输出条数上限设为 10。

多个限制为什么要特别注意顺序

限制参数会按书写顺序依次应用。print_stats(0.1, "init") 表示先取当前排序结果的前 10%,再从这部分结果里匹配函数名;最后可能少于预期的条目。

pstats print_stats 多个限制按顺序收窄并复用调用关系报告的静态关系说明图
图2:关系说明图,查看数量、比例与函数名限制的组合边界。
from pstats import SortKey

# 先取前 10%,再匹配 init;这是两层限制,不保证得到 10 条。
stats.sort_stats(SortKey.CUMULATIVE).print_stats(0.1, "init")

# 如果目标是“匹配 init 的结果里再取前 10 条”,先写匹配条件。
stats.sort_stats(SortKey.CUMULATIVE).print_stats("init", 10)

这两个写法没有谁绝对正确,区别在于你的问题是“全局热点中的 init”还是“init 函数中的热点”。先确定筛选集合,再决定数量上限,通常更符合后者的阅读预期。

调用者和被调用者报告也能复用限制

确定热点条目后,还可以用 print_callers() 查看谁调用了它,或用 print_callees() 查看它调用了谁。这两个方法接受与 print_stats() 相同的限制参数,因此可以保持同一套排序和筛选思路。

from pstats import SortKey

# 只查看累计耗时最高的 5 个函数及其调用来源。
stats.sort_stats(SortKey.CUMULATIVE).print_callers(5)

# 对同一批限制后的条目,查看它们继续调用了哪些函数。
stats.sort_stats(SortKey.CUMULATIVE).print_callees(5)

需要记住的是,限制针对的是要展示的函数集合,而不是把原始统计数据永久删除。若要换一个视角,重新调用 sort_stats() 和对应的打印方法即可。

最后记住这三个判断

  • 想改变“谁排在前面”,调整 sort_stats() 的键。
  • 想改变“这次显示多少”,给 print_stats() 传整数、比例或函数名匹配。
  • 多个限制按从左到右依次收窄,顺序不同,结果集合也可能不同。

相关问题

为什么我传了 10,结果不足 10 条? 如果前面已经有比例或字符串限制,后续的 10 只是在剩余集合中取上限。

应该使用 CUMULATIVE 还是 TIME? 想看调用链整体耗时用 CUMULATIVE,只看函数自身耗时用 TIME,关键是先明确优化目标。

排序会修改 profile 文件吗? 不会。排序和限制只影响当前 Stats 对象的报告展示。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>