编程学习网 > 编程语言 > Python > Python 3.15 发布了,真正值得关注的,不只是“又变快了”
2026
10-26

Python 3.15 发布了,真正值得关注的,不只是“又变快了”


一个命令行工具,只想看个版本号,却要先等一长串依赖加载完成。

给 CPU 密集任务加了线程,机器明明还有空闲核心,执行时间却没怎么缩短。

服务偶尔变慢,想看看卡在哪里,又不方便重启、改代码、加埋点。

Python 3.15 的几个重要变化,恰好对应这些日常问题。但先说一句反直觉的话:很多人期待「升级就变快」,这个期待本身就要打个问号。

有一个数字可以先记住:一个几乎不用任何依赖的version 子命令,冷启动能从249ms 降到 36ms。这个收益是真实的,但它来自「少做了工作」,而不是「解释器变快了」——这两件事,很多人混为一谈。

Python 3.15.0 已于 2026 年 10 月 9 日正式发布。现在值得讨论的,是这些能力到了什么阶段,以及它们能为你的项目解决什么问题——而不是一个笼统的「提速百分比」。

01、先分清:启动快、计算快、多核并行,是三种收益

THREE KINDS OF FAST

「Python 3.15 快了多少」,这个问题需要先拆开。

默认解释器执行代码的速度,决定单个任务的基础耗时;延迟导入减少启动阶段的工作;自由线程帮助可拆分任务利用多个核心;JIT 则尝试优化经常执行的代码路径。

把它们混在一起,就容易得出「升级后什么都快了」的结论。

Python 技术作者 Miguel Grinberg 用 3.15.0rc3 做过一组非正式测试。在递归斐波那契和冒泡排序两个单线程项目里,默认解释器相对 3.14 的提升,分别约为1.03× 和 1.04×。

这组结果可以说明:这两个程序没有出现大幅提速。

但测试作者也明确提醒,它们不代表解释器的全面性能表现,更不能直接推导出所有 Web 服务、数据任务和业务脚本的升级收益。

跑分提供线索,自己的负载才决定升级价值

如果你期待最容易感受到的变化,可以先看启动时间。

02、lazy import:让暂时用不到的依赖,晚一点加载

LAZY IMPORT

很多 CLI 都有一个不断变长的导入区:解析数据要用一个库,生成报告要用一个库,发送邮件又要用一个库。

结果只是执行一次--help,也要为这些功能付出启动成本。

Python 3.15 提供了显式延迟导入:

...python

lazy import json

print("程序开始运行")

def serialize(data):

  return json.dumps(data)

执行lazy import json 时先建立绑定,真正加载模块发生在首次使用时。

它尤其适合多子命令工具:看版本号,不必加载报告系统;处理文本,也不必提前初始化绘图依赖。

Coding Steve 用一个包含多个标准库及第三方依赖的 CLI 做过测试。在 M3 Pro 上,几乎不需要依赖的version 子命令,从约81ms 降到 18—19ms;在共享 Linux 容器里,从约249ms 降到 36—38ms。

这里有两个条件不能省略:第一,测试预热过缓存,统计的是后续进程启动耗时,不能称为严格冷启动。第二,当子命令最终需要使用全部顶层依赖时,逐条延迟导入的收益明显缩小。

lazy import 的收益,来自当前执行路径少做了工作

兼容旧版,可以从模块声明开始

需要同时支持旧版本 Python,可以使用:

...python

__lazy_modules__ = ["json", "pathlib"]

import json

from pathlib import Path

旧版仍按普通方式导入,3.15 可以延迟这些模块的加载。但这不等于「零风险」。

有一个边界尤其容易踩:模块被导入后如果立刻在顶层使用,加载照样立即发生。 比如下面的写法,延迟就失效了:

...python

__lazy_modules__ = ["dataclasses"]

from dataclasses import dataclass

@dataclass  # 装饰器在导入期就执行,还是立刻加载

class Config:

  host: str

此外,模块缺失时,错误可能推迟到首次使用;插件注册、初始化等导入副作用,也可能改变发生时间。

对服务来说,还要关注另一种变化:启动时间省下来的工作,可能转移到首次请求。所以,值得同时测启动耗时和首次调用延迟。

最合适的起点,是先看导入成本:

...bash

python -X importtime your_cli.py --help

找到重依赖,再逐项调整,比直接开启全进程延迟导入更容易判断收益。

03、无 GIL:重要进展是降低生态跟进的成本

FREE-THREADING

自由线程构建从 3.13 开始提供,3.14 已进入正式支持、仍然可选的阶段。因此,3.15 的变化不能概括成「无 GIL 终于从玩具变可用」。

它更重要的一步,是引入abi3t 稳定 ABI。ABI 可以理解为解释器与二进制扩展之间的一套接口约定,稳定 ABI 的价值,是让符合要求的扩展减少跨 Python 版本重复构建二进制包的负担。

符合相应要求的扩展,还可以声明同时兼容有 GIL 和自由线程构建。对普通用户,这件事没有跑分快那么直观;对维护者,它影响构建、测试和发布的长期成本。

自由线程进入真实项目,需要整个依赖链持续支持

构建支持无 GIL,不代表进程正在无 GIL 运行

导入未声明支持自由线程的 C 扩展,可能重新启用 GIL。官方说明,此时会打印警告。如果警告被启动日志淹没,就容易误判运行状态。

检查应放在项目实际依赖加载之后:

...python

import sys

import sysconfig

# 先加载项目实际使用的依赖

print("开关:", bool(sysconfig.get_config_var("Py_GIL_DISABLED")))

print("当前 GIL 是否开启:", sys._is_gil_enabled())

还要区分另一个问题:某些扩展计算本来就会释放 GIL。因此,观察到线程加速,不能单独证明解释器已经关闭 GIL。

能并行,也要付出协调成本

自由线程让纯 Python 的 CPU 密集任务有机会利用多个核心,却不会自动消除共享对象竞争。

CPython 的一个公开 issue 就报告过:在特定测试中,多个线程调用共享的functools.partial,吞吐量随着线程增加反而下降。报告将问题追溯到一次内存安全修复新增的引用计数操作,引发了共享对象上的竞争。

这个案例说明:即使代码没有数据竞争,原子操作、锁和缓存争用,也可能让扩展性变差。评估线程池能否替代进程池,要一起看结果正确性、依赖兼容性、共享状态、吞吐量和内存。关闭 GIL,只是评估的开始。

04、JIT:进展明显,但「白捡两位数提速」说得太满

EXPERIMENTAL JIT

3.15 的实验性 JIT 有明显升级。官方 pyperformance 结果显示:

x86-64 Linux

相对启用完整优化的标准解释器,几何平均提升约 7%—8%。

AArch64 macOS

相对启用完整优化的尾调用解释器,提升约 11%—12%。

这两个数字有各自的比较基线,不应该直接写成「所有 Mac 用户升级就快 12%」。不同负载的表现也有差异,部分测试会变慢。

紧密的纯 Python 计算循环,可能获得很可观的收益;如果大量时间耗在网络等待、数据库或扩展库内部,结果就需要另外评估。尤其是 Pandas、Polars 这类工具,不能因为脚本入口使用 Python,就默认其主要耗时会被 CPython JIT 优化。

启用前还要确认:当前解释器构建包含 JIT 支持。

...python

import sys

jit = getattr(sys, "_jit", None)

print("构建支持 JIT:", bool(jit and jit.is_available()))

print("进程启用 JIT:", bool(jit and jit.is_enabled()))

在支持的构建中,可以通过PYTHON_JIT=1 在进程启动时启用。它仍是实验性功能,比较有价值的做法,是在测试环境里用同一批数据、同一套依赖,对照启用前后的实际表现。

05、frozendict 和推导式解包:让常见意图写得更直接

EXPRESSIVENESS

性能之外,3.15 也补充了两种日常表达能力。

frozendict:不可变映射进入内置类型

有时,我们需要传递一份配置,并明确它不能被修改;或者希望把一组参数作为缓存键。3.15 新增内置类型frozendict:

...python

config = frozendict(host="localhost", port=5432)

print(config["host"])

# config["port"] = 3306  # 不允许修改映射项

它保留插入顺序,但相等比较不依赖插入顺序。还有两个边界很重要。

第一,不可变是浅层的。 如果值是一个列表,外层映射不能增删改,不代表列表内容被冻结。

第二,只有键和值都可哈希时,整个 frozendict 才可哈希。

...python

hash(frozendict(mode="fast"))  # 可以

# hash(frozendict(items=[1, 2]))  # 值是不可哈希列表,不能计算哈希

它也不是dict 的子类。如果接口确实接受一般映射,可以考虑使用collections.abc.Mapping 判断;如果接口需要修改传入对象,就应保留相应约束。

推导式解包:展平和合并更简洁

合并一组列表,可以写成:

...python

groups = [[1, 2], [3, 4], [5]]

flat = [*group for group in groups]

# [1, 2, 3, 4, 5]

合并一组字典:

...python

parts = [{"a": 1}, {"b": 2}, {"a": 3}]

merged = {**part for part in parts}

# {"a": 3, "b": 2}

重复键由后面的值覆盖。这种语法适合表达展平和合并,不必为了使用新特性,把包含复杂筛选、转换的推导式也改得过于紧凑。

06、Tachyon:先知道时间花在哪里,再决定怎么优化

SAMPLING PROFILER

讨论升级时,最容易遗漏的能力,是性能分析。

3.15 新增的 Tachyon 采样分析器,可以运行脚本,也可以在具备相应系统权限时附加到运行中的进程:

...bash

python -m profiling.sampling run script.py

python -m profiling.sampling attach 12345

生成交互式火焰图:

...bash

python -m profiling.sampling run \

  --flamegraph -o profile.html script.py

它通过周期性获取调用栈,估计程序的热点。对于不方便修改代码、重启服务的场景,这种方式很实用。但采样结果具有统计性质:短任务可能采样不足,执行很快的函数可能被遗漏,也无法提供精确调用次数。

Python 此前已有 py-spy、Austin 等第三方工具,不能说 3.15 之前做不到。Tachyon 的意义,在于标准库直接提供了一条低开销采样分析路径。

另外,3.15 默认启用帧指针,也改善了系统级工具的栈回溯基础。这有助于分析运行时与原生扩展,但不意味着任何工具都能自动获得完整的 Python 源码调用栈。

07、升级前,还有两个比跑分更现实的变化

ENCODING & GC

UTF-8 默认开启:旧文件不会自动转换编码

3.15 默认启用 UTF-8 模式。对依赖系统默认编码的旧脚本,尤其是 Windows 上处理历史文本文件的程序,这可能改变行为。

例如,一个实际使用 GBK 编码的文件,不会因为解释器升级就变成 UTF-8。省略encoding 的读取操作,可能因此报错或出现乱码。应根据数据实际编码明确指定:

...python

with open("data.txt", encoding="utf-8") as f:

  text = f.read()

with open("legacy.txt", encoding="gbk") as f:

  legacy_text = f.read()

也别只检查open(),子进程文本输出等依赖默认编码的路径,同样值得测试。

GC 调整:别沿用早期 3.14 的调参经验

3.14 曾引入增量垃圾回收设计,随后又作出调整。官方文档记录,3.14.5 重新引入中间代,以维持此前的分代回收行为。因此,这件事不能简单归纳为「3.14 有问题,3.15 才修好」。

对维护者更实际的提醒是:如果针对早期 3.14 调整过 GC 阈值、监控指标或回收策略,升级时应重新验证。默认构建与自由线程构建,也不能不加区分地套用同一套假设。

08、到底该不该升级?

UPGRADE CHECKLIST

可以先给项目增加一套 3.15 测试环境,再按问题选择验证方向:

项目情况

优先验证

CLI 启动慢

导入耗时、延迟导入、首次调用延迟

纯 Python 计算占主导

JIT 与自由线程的实际收益

多线程扩展性差

任务粒度、共享状态与对象竞争

数据处理脚本

主要耗时属于解释器还是扩展库

Windows 旧脚本

文件和子进程的编码行为

长期运行的服务

延迟、内存、依赖兼容性与性能热点

测试时,至少记录解释器版本、构建类型、GIL 和 JIT 状态。比较启动时间时说明缓存条件,比较多线程时说明任务总量和基线。

Python 3.15 带来的变化,覆盖了从启动、执行到排查问题的多个环节。对一个具体项目来说,最有价值的升级理由,应该能对应到一个已经观察到的问题,以及一组可以复现的改善。

以上就是“Python 3.15 发布了,真正值得关注的,不只是“又变快了””的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。 

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取