Python 3.13 的 Experimental JIT 仅在运行时对内存中满足条件的纯 Python 函数动态编译为机器码,不参与包安装、构建或分发,不落地磁盘,不跨进程复用,且仅限 x86-64 平台生效。

Python 3.13 的 Experimental JIT 不会编译包,也不会影响包的安装、构建或分发过程——它只在运行时对满足条件的函数做动态机器码替换。
jit 编译发生在 import 之后,与 pip install 无关
JIT 编译器不介入 pip install、setup.py 或 pyproject.toml 构建流程。它完全不读取源码文件或 wheel 包结构,只监控已加载进内存的函数对象的执行行为。一个包是否被“编译”,取决于它内部是否有函数被反复调用超过阈值(默认 50 次),而不是它怎么被打包或安装的。
-
pip install numpy后,np.array()不会被 JIT 编译——因为它是 C 扩展,字节码极少 -
pip install mypackage后,如果mypackage.calc()是纯 Python 循环且被调用 51 次,才可能触发 JIT - 打包工具(如
build、setuptools)完全感知不到 JIT 存在
为什么有人觉得“包被编译了”?
常见误解来自两类现象:
- 误把
.pyc字节码缓存当 JIT 编译结果:JIT 生成的机器码不落地到磁盘,也不写入__pycache__,它只驻留在进程内存中 - 看到
import耗时变长:首次导入含热点函数的模块时,JIT 还没启动;但后续调用触发编译,可能让开发者误以为“导入阶段做了什么” - 混淆
--with-jit编译选项:这是构建 CPython 解释器时的配置,影响的是解释器本身能否启用 JIT,和第三方包无关
真正受影响的包场景只有两种
不是所有包都会受益,只有极少数满足全部条件的包内函数才可能被 JIT 处理:
立即学习“Python免费学习笔记(深入)”;
- 函数必须是纯 Python 实现(不含
ctypes、cffi、numpy、math.sqrt()等 C 调用) - 函数不能含
eval()、exec()、getattr(obj, name)这类动态操作(JIT 无法静态分析控制流) - 函数需被同一进程内重复调用 ≥50 次(比如 Web 请求循环中的数据清洗函数)
- 运行平台必须是 x86-64 Linux 或 Windows;ARM64(包括 Apple Silicon)上
sys.jit_status()返回{'enabled': True, 'backend': 'none'}
最易被忽略的一点:JIT 编译结果不会跨进程复用。哪怕你反复运行同一个脚本,每次启动都是全新进程,都要重新触发 50 次调用才能编译——它不是“一次编译,永久生效”的 AOT 工具。


















