让 AI 优化 Python:先给它一份耗时热点报告

阿哲 Lv.2 2026/10/25 09:48:28 浏览 0

一段 Python 跑得慢,交给 AI 修改时,最好连“时间花在哪”一起给它。只贴源码让它猜,容易改了一堆写法,真正重复做的工作还在。

附件用标准库 cProfile 跑一个固定订单样例,输出两份可以直接读的热点报告。数据先准备好,只分析汇总函数;生成数据、检查结果和写文件都放在分析范围之外。没有调用模型,慢版和对照版都是手写的教学代码。

解压后在材料目录运行,需要 Python 3.10+,本次实际用 Python 3.12.14:

python verify.py
python run_profile.py profile-output

profile-output 必须是新目录。报告中的秒数会随机器和运行状态变化,不把某个耗时值当作测试通过条件。

这份固定输入是2400笔合成订单、81个给定客户。正常会输出:

equivalent=True orders=2400 customers=81 paid_orders=1870 paid_cents=78893541
profiled=slow; reports=cumulative.txt,time.txt; not a benchmark

输出目录里的 result.json 是逐客户结果,summary.json 是本次样例摘要。equivalent=True 来自两个实现完整输出的比较,不只是核对总金额。

先读哪一列

cumulative.txt 按 cumtime 排序:这个函数连同它调用的其他函数,一共占了多少时间。先看它,能找到哪个上层任务承载了主要耗时。

time.txt 按 tottime 排序:只算这个函数自身,不包含子调用。再看这一份,才能继续往具体函数里找。ncalls 是调用次数,末尾的 filename:lineno(function) 可以对应回包里的源码。这是函数级报告,行号用于定位函数,不是这一行单独花了多少时间。

同一段执行时间可能同时出现在上层和子函数的 cumtime 里,不能把它们直接相加。

这次实际报告中,matches_paid_customer 调用了 194400次,对应 orders.py 的第42行。81个客户 × 2400笔订单,正好是这个数;顺着调用它的 slow_summary 看源码,就能看到逐客户筛选整份列表的地方。报告中的行号只对应包内这版文件,改过源码后要重新生成。

样例的慢版为每个客户重新扫描整份订单。对照版改为遍历订单一次,同时累加各客户的金额。这里不是只把一个循环写短:它减少了重复扫描,但下面这些规则必须保留:

  • 只有 paid 订单计入金额,使用整数分。
  • customers.json 中没有订单或只有待付、取消订单的客户,也保留0笔、0分。
  • 客户顺序按 customers.json 给定的顺序,不擅自改成按金额排序。

订单引用不在客户列表中的客户,会在预检时报错,不自动新增客户。

这也是为什么包里同时放了等价检查。定位到热点,并不代表可以删掉看起来“麻烦”的业务规则。

把自己的函数换进去时,可以保留下面这个最小分析方式;target 和 data 需要替换成真实函数及其已经准备好的输入:

import cProfile
import pstats
from pstats import SortKey

profiler = cProfile.Profile()
result = profiler.runcall(target, data)
pstats.Stats(profiler).sort_stats(SortKey.CUMULATIVE).print_stats(10)
pstats.Stats(profiler).sort_stats(SortKey.TIME).print_stats(10)

它会真的执行 target(data);先在自己可运行的小样本上分析,再扩大范围。若改成分析整个脚本,导入、构造数据和输出也可能占进报告,不再是同一段工作。

给 AI 的材料一起交齐

除了这两份报告,还要给对应源码、数据规模和正确性测试。下面这段要求可以直接复用,包里另有填好本例约束的完整版本:

请依据所附源码、两份cProfile报告和测试定位耗时热点。
先指出函数名、对应行号、调用次数,以及你引用的是cumtime还是tottime。
解释重复工作在哪里,再给出最小修改;不要只凭函数名称猜原因。
保留输入校验、输出内容、金额精度、空输入行为和原有顺序规则。
不得通过删数据、跳过状态判断或放宽测试来减少耗时。
先运行现有正确性测试,再补充受这次改动影响的边界测试。
没有实际运行时明确写未验证,不声称通过或更快。
若要报告提速,另用不启用profiler的重复计时,列环境、输入和各轮结果。

cProfile 用来找热点,会引入额外开销。这篇没有做独立基准测试,也没有给出加速倍数;两份报告不能当作模型优化效果的成绩单。固定样例的等价检查不能保证真实业务里的所有输入都等价;本例也没有退款、多币种或折扣规则,替换业务时需要另定预期。

本地实际跑过11组检查,包括完整输出比较、客户顺序和零项、空输入、未付状态、整数精度、错误金额、未知客户和状态、坏JSONL行号,以及已有输出保护。最终ZIP已在新目录解压复跑,主命令和11组检查都通过;可用包内 verify.py 重现。

同一路径再次运行主命令,会以退出码2报告 output must be a new directory,不会覆盖已有结果。输出写入或存储异常时仍需检查退出状态,不能只看到目录存在就认为四份文件都已生成。

下载订单样例、两种实现、热点报告、优化提示词和验证脚本(ZIP,12个文件)

参考:Python 3.12 标准库 cProfile、pstats、timeit 文档,2026-10-25查阅。

评论 0

发表评论

登录后参与讨论

登录

暂无评论