最近刷技术资讯的话,应该没少看到“Python 3.13性能提升巨大”“速度直追C语言”这类说法。作为一个把Python当主力语言用了快十年的开发者,我对这类宣传词的第一反应是:先看源码,再看benchmark脚本,最后拿自己项目跑一遍。毕竟性能这事的体感差异太大了,同一个版本,写爬虫的和写数值计算的人能给出完全相反的评价。
这篇文章就围绕Python 3.13的性能提升来聊。我会从官方release notes里的真实数据出发,把第三代自适应解释器、copy-and-patch JIT、无GIL构建这几块核心内容拆开讲清楚,再补上一些散落在文档角落但实际有用的优化细节,最后给出我自己升级前后的实测建议。适合正在犹豫要不要从3.11/3.12迁移到3.13的人,也适合想搞明白“Python性能优化到底优化在哪”的读者。
1. 先泼盆冷水:网上说的“性能翻倍”到底靠不靠谱
1.1 官方benchmark给出的真实涨幅
先说结论:Python 3.13相对3.12的性能提升,官方pyperformance基准测试给出的数据大概是平均5%左右,部分热点场景能到10%-30%,但离“翻倍”差得很远。
要知道Python 3.11发布时官方宣称相对3.10提升了10%-60%,那是一个大版本叠加了两个大版本才换来的“明显体感”。3.12相对3.11又挤了一点牙膏,到3.13这个版本,GIL默认还在,JIT默认还是实验性开关,常规构建下的纯CPU性能进步属于“稳步推进”级别。
我见过不少测试截图,测出来3.13比3.12快了50%甚至更多。这种结果通常不是造假,而是选了非常特定的微基准,比如把同一个纯Python循环跑几十万次,或者在已经高度特化的容器操作上来回跑。这种benchmark能说明JIT和特化解释器在工作,但没法代表你手上的业务代码。
实际体感更接近这样一个规律:代码越简单、循环越密集、越“只靠Python自身运算”的项目,3.13的提升越明显;一旦项目里80%的时间消耗在numpy、pandas、数据库驱动这些C扩展库里,那3.13带来的整体收益可能连2%都不到。
1.2 为什么有人会测出“翻倍”的效果
这个问题值得拆一拆,因为它直接关系到你怎么看待性能测试。
有一种情况是拿3.13的free-threaded无GIL版本去跑多线程CPU密集任务。GIL去掉之后,4核机器上跑满4个Python线程,本来只能占到1个核的量,现在能占到多个核,测出来“2倍”“3倍”都不稀奇。但那是并行能力提升,不是单线程执行速度提升,两者必须分开评价。
另一种情况是打开了JIT之后,某些热点函数的执行路径从“解释器循环”变成了“机器码直接执行”。这种场景下测出20%-50%的提升是有可能的,尤其在函数调用密集、属性访问密集的代码里。但JIT对不热的一次性代码毫无帮助,对已经跑到C库里的代码也没有帮助。
还有一种情况纯粹是版本叠加效应。比如你拿3.10和3.13对比,3.11已经快了一大截,3.12又优化了一部分,3.13再叠加一点,总体看上去确实有接近翻倍的数据。但那是三个大版本的总和,不是3.13这一个版本的功劳。
所以在看任何“性能提升”宣传时,先问三个问题:基准是什么版本?跑的是什么类型的工作负载?用的什么构建(标准构建、JIT构建还是无GIL构建)?把这三点对齐了,才能判断一个版本对你到底有没有意义。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 第三代自适应解释器:底层字节码执行方式变了
2.1 从按字节码逐条执行到“带缓存的特化执行”
聊Python 3.13性能,绕不开PEP 659在3.11版本引入的自适应特化解释器(specializing adaptive interpreter)。这个机制到3.13已经是第三代了,也是当前默认构建下性能提升的主要来源。
理解它的最好方式,是拿一个简单的属性访问例子拆开看。你在代码里写obj.attr,编译器会生成一条LOAD_ATTR字节码。在3.11之前,解释器每次执行到这条指令,都要走一遍完整的属性查找流程:拿到对象的类型指针、在类型里查MRO、找描述符、判断是否需要调用__getattribute__……一套流程下来几十上百个C函数调用。
但如果这个obj在生产环境里几乎永远是同一个类,那这套完整流程里90%的步骤是白做的。自适应解释器做的事情就是:先按通用方式跑几遍,收集运行时类型信息,然后根据这些信息把字节码替换成更专门的版本。
以`LOAD_
