2026-10-12 · 原文发布日
让Codex用Python 3.15新剖析器找性能瓶颈
Simon Willison演示了一种省力的性能分析做法:让Codex直接调用Python 3.15内置的采样剖析器profiling.sampling跑他的web-edit应用,产出火焰图和源码热力图。作者称结果显示混合换行符的保留逻辑占据了大部分CPU栈,而且必须采样所有线程——绝大多数栈来自AnyIO的工作线程,只看主线程会完全漏掉。对有Python项目的人来说,这给出了一句可复用的提示词思路:先让agent调研,再直接生成火焰图和热力图演示。
原文要点
Simon Willison让Codex(GPT-6 Astra Extra High)用Python 3.15内置采样剖析器profiling.sampling分析他的web-edit应用,提示词思路是『先调研,再做火焰图和热力图演示』。作者报告:preserve_endings出现在15296个CPU栈的64.8%中,SequenceMatcher.find_longest_match贡献38.3%的叶子样本;95.1%的栈来自AnyIO工作线程,只采样主线程会完全漏掉热点。以上百分比与模型名为作者所述,本文不复核。
这次做成什么
学会一条可复用的agent性能分析套路:让Codex或同类编程agent先调研你的项目,再调用Python 3.15的profiling.sampling对所有线程采样,产出火焰图与源码热力图,并据此定位真正的热点函数。
准备什么
- 已安装Python 3.15(profiling.sampling为新版本内置模块,旧版本没有)
- 一个可本地运行的Python项目,最好是带并发框架(如AnyIO/asyncio)的应用
- Codex CLI或其他能执行终端命令、读写项目文件的编程agent
- 项目能在本地跑起来并施加负载(测试脚本、压测工具或手工操作)
具体怎么做
确认环境并准备一个可压测的项目
终端运行python3.15 --version确认解释器版本。准备一个能跑起来的应用:可以是自己的FastAPI/AnyIO服务,也可以像作者那样从PyPI装一个小型web应用做实验。明确启动命令和触发负载的方式(例如一段循环请求的脚本),这两件事agent后面会用到。
向agent下达『先调研再演示』的两段式指令
把下方提示词发给agent,替换项目名和启动方式。关键是模仿作者的结构:第一,要求它先调研——读懂项目入口、依赖和如何产生有代表性的负载,不要上来就采样;第二,要求它用Python 3.15的profiling.sampling在负载下采样并生成火焰图和源码热力图。profiling.sampling的确切命令行参数本文未从原文获得,让agent自行查阅3.15文档确认,不要凭记忆编造。
检查采样是否覆盖所有线程
这是本文最有价值的教训:作者的应用95.1%的栈在AnyIO工作线程上。拿到结果后先问agent:采样配置是否包含全部线程?让agent在报告中列出各线程的栈占比。如果报告里几乎只有主线程,说明采样范围不对,要求重采,否则你会像作者警告的那样完全漏掉真正的热点。
读图定位热点并决定是否优化
看火焰图最宽的帧和热力图最热的源码行,让agent给出:热点函数名、出现在多少百分比的栈中、叶子样本占比(如作者报告的64.8%与38.3%这种口径)。注意这些是采样估计,不是精确计时;决定是否优化前先让agent解释该热点在什么负载条件下出现,避免为罕见路径做无谓优化。
可直接复制的材料
发给agent的性能剖析提示词(本站扩展版)
本站根据作者一句话提示词思路扩展的独立版本;作者原句是让其调研web-edit再做火焰图和热力图演示,未包含线程要求等细节。花括号处替换为你自己的信息。
我需要你帮我用Python 3.15内置的profiling.sampling剖析器分析本项目的性能,分两步执行:
第一步先调研,不要急着采样:阅读项目代码,告诉我应用的入口、使用的并发框架、哪些路径最可能消耗CPU,以及如何在本地启动它并施加有代表性的负载。
第二步做演示:用profiling.sampling在负载运行期间采样(请先查阅Python 3.15官方文档确认该模块的用法和参数),生成火焰图和源码热力图,保存到项目下的profile-output目录。
硬性要求:采样必须覆盖进程的所有线程,不要只采主线程;完成后在报告里列出各线程的栈占比、出现频率最高的5个函数及其栈占比、叶子样本占比最高的5个函数。所有数字注明来自采样估计。
项目启动方式:{填写你的启动命令}
负载产生方式:{填写压测脚本或操作说明}输入与输出示例
本站虚构演示,数字为说明报告口径而编,非实际剖析结果;你的项目数字必然不同。
输入
对一本站虚构的Markdown批处理CLI(Python 3.15,内部用AnyIO并发读文件)发送上述提示词,负载为脚本连续转换500个测试文档。对应输出
agent报告示意:共记录9 840个CPU栈,其中92.7%来自AnyIO工作线程、7.3%来自主线程;栈占比最高函数:normalize_whitespace占58.2%,render_links占21.4%;叶子样本占比最高:re.Pattern.sub占33.6%。结论:空白符归一化是正则在逐行调用,建议改为整文档一次替换。火焰图与热力图已写入profile-output/。做完检查这些
- agent先输出了调研结论(入口、并发框架、负载方式),然后才开始采样
- 报告明确列出各线程栈占比,工作线程占比与火焰图主体一致
- 报告同时给出栈占比(inclusive口径)和叶子样本占比(exclusive口径)两组数字
- 火焰图文件和热力图文件真实生成在指定目录且能打开查看
容易卡住的地方
- profiling.sampling是Python 3.15新增模块,用3.14或更早版本会直接找不到模块
- 只采样主线程是最致命的错误:并发应用的绝大多数CPU消耗在工作线程上,作者案例中占95.1%
- 采样剖析给出的是统计估计,样本少或负载太短时百分比波动很大,别把单次结果当精确测量
- agent可能凭训练记忆编造该模块的命令行参数,务必让它对照3.15官方文档核实
- 没有代表性负载时火焰图反映的是启动开销而非业务热点,先准备好压测方式
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Profiling web-edit with Python 3.15: flame graphs and source heatmaps
- 原作者
- Simon Willison
- 原始发布日期
- 2026-10-12
- 来源
- https://simonwillison.net/2026/Oct/12/python-3-15-web-edit-profiling/