PyPy 8.0 发布:从稳定 ABI 看性能工程为何仍不可替代

先说结论

  1. PyPy 8.0 是主版本升级,核心不是 JIT 跑分,而是构建环境与 ABI:Linux 构建基线从 gcc5 换成 gcc14、glibc 基线升至 2.28,并首次提供 Python 3.12 beta 解释器。
  2. 官方目标明确:让 PyPy 能使用 CPython 3.12 的 cp312-abi3 有限 ABI 轮子;官方博客写明部分头文件和导出符号已兼容,但导入机制与 pip/uv 生态仍需后续工作。
  3. RPython 代码生成试了 computed gotos 与更积极内联,官方承认“性能提升不如预期”——这是宝贵的负结果,说明性能工程没有一键魔法。
  4. 官方放弃 HPy 后端、重新启用 pyhdrdump 做头文件对比,属于典型底层兼容性工程,AI 模型很难替代这类需要长期实测与跨项目协作的工作。
  5. 本文判断:AI 时代不是性能工程过时,而是更值钱;不是所有问题都该用模型解决,ABI、内存布局、JIT 和生态兼容尤其如此。

证据与过程

为什么直接跳主版本号:glibc2.28 与 gcc14 构建基线

PyPy v8.0.0 官方发布说明开篇就解释,这次从 7.x 跳到 8.0.0,主因不是解释器功能大改,而是 Linux 构建产物基线变了:构建机从基于 AlmaLinux 8 的 manylinux_2_28 镜像开始,编译工具从 gcc5 换成 gcc14,因此编译后的 tarball 至少需要 glibc 2.28。官方博客给出一个参照:Ubuntu 24.04 使用 glibc 2.39。这是官方数据,不是社区估算。原文片段是:“These use gcc14 instead of the gcc5 previously used. So our compiled tarballs will require at least glibc2.28, which should be universally supported by now (Ubuntu 24.04 uses glibc2.39).”

这个变化对用户来说可能没有直接感知,但对二进制分发影响很大:如果系统 glibc 低于 2.28,新的 PyPy 预编译包就无法运行。官方认为 2.28 现在应该已经普遍支持。根据官方给出的两个日期(上次发布 2026-05-26,本次 2026-09-19),可以推算出间隔约 3 个多月,这是自己推算,不是官方给出的数字。

下面这个检查 glibc 依赖的命令,是社区中常见的一种做法,不是 PyPy 官方文档给出的命令:

# 检查 Linux 二进制所需 glibc 版本的常用做法(非官方命令)
objdump -T pypy3 | grep GLIBC_ | sed 's/.*GLIBC_//' | sort -V | tail -1
# 按官方发布说明,8.0 编译产物预期不会显示高于 GLIBC_2.28 的要求

注意上面代码块里的“预期不会显示高于 GLIBC_2.28”是根据官方博客的 glibc2.28 基线做的推算,属于自己推算,不是官方文档直接给出的命令输出。

cp312-abi3:比 JIT 加速更紧迫的生态问题

PyPy 团队在 v8.0 最重要的主线是 cp312-abi3 支持。官方博客写道,从 v8.0.0 开始,PyPy 把仅 PyPy 才有的对象扩展“隐藏”在传给 C 扩展模块的指针之前,目标就是让 PyPy 能使用为 CPython 3.12 及以上编译的 cp312-abi3 有限 ABI 轮子。官方列出的已完成项包括:PyPy 的 C 头文件(含 PyObject 等结构定义)在定义 Py_LIMITED_API=0x030C0000 时与 CPython 的 C 头文件兼容;PyPy 不再对有限 API 的导出函数名做改写(例如不再把 PyTuple_New 导出成 PyPyTupleNew)。官方也明确列出仍缺失的部分:导入机制还需要学会接受 abi3.so 共享对象,pip、uv 等生态也需要接受 cp312-abi3 轮子作为合法候选。

这不是一夜之间的决定。在 PyPy 仓库的 issue #3397 中,社区早已提出类似的稳定 ABI 需求,背景是 cryptography 等项目在 PyPy 下需要依赖 Rust 编译链,维护者希望有稳定的 PyPy wheel 来减少用户安装成本。这是社区二手需求,不是官方承诺。官方博客也提到 cibuildwheel 支持构建 PyPy wheel,这属于第三方工具,不是 PyPy 官方产品。

从工程角度看,支持 cp312-abi3 的价值是生态兼容而非 JIT 提速:很多 Python 库只为 CPython 提供 abi3 轮子,如果 PyPy 能直接安装这些轮子,PyPy 用户的安装成本会大幅下降。按官方博客的写法,可以这样理解:PyPy 团队认为兼容性比短期性能数据更重要。

RPython 代码生成:性能工程没有魔法银弹

官方博客还披露了 RPython 代码生成的改进尝试:“We now use computed gotos and more aggressively inline code. While this produces more compact sources, it does not boost performance as much as we wished.” 这是官方原话。也就是说,团队尝试了计算式 goto 和更激进的函数内联,生成更紧凑的 C 源码,但性能提升“不如预期”。

这个负结果值得单独拿出来说。解释器性能工程中,很多优化听起来很合理,例如减少间接跳转、增加内联,但真实机器上的分支预测、指令缓存、寄存器压力等会抵消理论收益。这种经验只能通过真实基准测出来,无法通过一个 prompt 生成准确结论。AI 编程工具可以帮你写出 computed gotos 的代码,但不能替代你判断是否应该启用它,更不能替你跑全套回归和性能对比。

放弃 HPy,重新启用 pyhdrdump

官方博客宣布放弃了内部 HPy 后端。原因是 HPy 项目虽然用 handle 代替指针的原型不错,但没有吸引到足够支持者成为新标准。代码仍保留在 PyPy 代码库中,可通过构建选项开启。官方同时重新启用了基于 clang 的 pyhdrdump 工具,用于对比 PyPy 和 CPython 的头文件。这个工具对 ABI 兼容工作至关重要:只有逐字段、逐签名地比对,才能确认 PyPy 是否真的符合 CPython 的 C API 约束。

这再次说明,底层兼容性工程需要专门的工具和人工审查,而非泛化的代码生成。AI 模型可以生成头文件片段,但无法保证 32 位、64 位、ARM 等平台下的 ABI 布局一致,也无法自动修复 PyObject 结构差异带来的内存问题。

自己的判断/清单

  1. 不用等“AI 替代性能工程”:PyPy 8.0 的例子表明,性能工程的核心是长期试错与跨生态协作,模型只能辅助代码编写,不能替代实测与架构取舍。
  2. 如果你是 C 扩展库维护者:优先看一遍 PyPy 官方发布说明中的 cp312-abi3 部分,确认你的项目是否能在 PyPy 3.12 beta 下直接使用 abi3 轮子;如果不能,考虑提供 CFFI 版本,或等官方补齐导入机制和 pip/uv 生态后再发布 PyPy 轮子。
  3. 如果你在 AI 编程工具中处理底层代码:不要只跑单测,应配合头文件对比工具(如 pyhdrdump)或 ABI 检查命令,避免模型生成出“看起来对、实际破坏 ABI”的代码。
  4. 性能负结果也有价值:官方承认 computed gotos 和更积极内联提升不如预期,这种记录应该被更多团队学习。没有负结果,整个社区会重复踩坑。
  5. 谨慎评估 PyPy 3.12 生产使用:官方标注其为 beta 质量,且导入机制与 pip/uv 支持尚未完成,建议先在非关键路径试运行。

这次没核实的

  • PyPy 8.0 相比 CPython 3.12 的具体性能倍率:官方发布说明没有提供,给定的社区来源中也没有可信基准,因此未能核实。
  • PyPy 8.0 在 AI 工作负载(例如 PyTorch、NumPy 等生态)下的表现:官方发布说明未提及,社区来源也未提供对照数据,因此未能核实。
  • PyPy 3.12 beta 的具体已知 bug 列表:官方仅标注 beta 质量,未列出细节。
  • issue #3397 中提到的 cryptography 依赖 Rust 对 PyPy 用户的具体影响程度:未能从官方博客核实,仅作为社区需求背景。

参考来源

评论区

0 条评论

登录后可评论。

小土豆 129 阅读