译者注:
如果对Pyston还不了解,可以阅读由Pyston的Leader——Kevin Modzelewski写的Dropbox Pyston介绍,中文版在此。以及我对Pyston的一点粗浅评价。同时也可以阅读英文的FAQ。
我们非常激动向大家发布 Pyston 0.4,这是这款高性能 Python JIT 的最新版。该版本中含有众多改进,最重要的是,Pyston已经能够渲染Dropbox的页面,且在我们的性能测试中比 CPython 的快 25%。同时我们也非常激动的向大家展示 Pyston 的 logo。
过去八个月来,Pyston从0.3升级到0.4,这期间含有2000多个commit,是0.2到0.3的三倍。虽然这次从0.3到0.4用了八个月,但今后将每四个月发布一次,
兼容性提升
0.4中实现了许多Python特性,虽然任何一个特性并不值得大书特书,但加起来就相当可观了。这些特性包括:
- 支持Unicode类型
- 多重继承
- 支持weakref和finalizers(
__del__
),包括正确的析构顺序。 - with语句
- exec s in {}
- 改变已有函数的参数的值和个数。设置
func_code
、func_defaults
、func_globals
。 - 引入了hooks
- Set解析(类似列表解析)
- 改进了C API
- 支持更多的标准命令行参数
- 在REPL(即交互式命令行中)支持多行语句,0.3中只支持单行语句。
- Traceback和frame对象,locals()
总之,这意味着Pyston几乎支持所有Python语义。另外,Pyston还实现了许多用法,这些用法一般不认为是Python的特性,但一些常见的第三方库中会用到。如支持内置函数中所有的参数组合(如将None
传递给map
),或一些技巧性的用法,如修改sys.module
来改变一条导入语句的结果。
这些新特性意味着Pyston能支持许多常见的库。现在Pyston已经能运行许多常见库的测试套件,如Django和Sqlalchemy,今后会支持更多库。Pyston现在还将CPython的测试套件纳入考察范围,目前已将153个CPython测试文件(CPython共有401个)添加到Pyston的测试套件中。
Pyston还初步支持了NumPy。目前,NumPy支持对Pyston的优先级并不高(Pyston最初的目标并不会用到NumPy),但我们依然花了一点时间来让一些简单的NumPy示例可以运行。
最重要的是,现在Pyston可以运行Dropbox的主服务器,并可以渲染其中的许多页面。虽然还有许多工作需要完善(如让测试套件运行、添加性能测试,这样才能量化性能提升并进行比较),但我们已经获得了可喜的成果。
C API
Pyston 0.4改进了C API的支持,这对运行Dropbox服务器帮助很大。CPython拥有C API,用来编写扩展模块。在Pyston 0.2时添加了基本的C API兼容层,将Pyston的API转换成CPython的C API。现在这个C API的兼容性已经得到大幅改进,不仅能支持C扩展,还能运行CPython的内部代码。这意味着如果需要支持新的API函数,可以直接使用CPython的实现,而不用在Pyston的API上实现了。
由于Pyston中使用了越来越多的CPython代码实现了许多API。所以现在Pyston的C API已经不单单是个兼容层。CPython现在就是Pyston运行时的基础,而不是Pyston试图兼容的目标。这对运行Dropbox的服务器也很重要,因为现在能直接使用CPython中含有很多技巧的实现。如Unicode处理。如果全部自己从头实现Python运行时的话,那么时间都花在造轮子上面,现在也就达不到运行Dropbox的地步了。
性能提升
同样,Pyston 0.4也包含许多性能上的改进,包括:
- 添加自定义的C++ exception unwinder。根据Pyston特的特殊情况进行定制,让C++异常效率提升两倍。
- 如果认为某个异常较为常见,则使用较快的基于返回代码的(return-code-based)异常,如特殊的返回代码,或运行时分析。
- 添加baseline jit层,位于解释器层和LLVM JIT层之间。这一层能让代码的执行速度接近LLVM层,但降低Pyston的启动延迟。
- 新的磁盘缓存技术,消除LLVM层中非初始运行的开销。
- 诸多Tracing改进,能生成更好的代码,并支持更多的情形。
- 新的C API调用约定,大幅提升C API的调用速度。
- 将部分内建模块转成共享模块,提升启动速度。
- 添加PGO构建,并在普通构建中使用其函数顺序。
这里面没有列出对LLVM层的优化。Pyston的LLVM层在微基准测试中表现很好,但在“实际代码”中,即使知道所有对象的类型,表现也不好。这是因为了解对象的类型仅仅是动态性的第一步,即只能知道应该调用哪个函数,但这个函数本身经常含有动态调用。例如,如果调用len()
函数,可以消除动态分配并直接调用len()
的实现。但这个实现会在内部动态调用arg.len()
。而len()
是非常常见的,可以在LLVM层中特殊处理,这种多层次动态性非常常见,现在不断以来Pyston中的mini tracing JIT来同时处理所有层。这让能对每个单独个字节码获得很好的结果,但缺点是无法很好的在字节码之间进行优化。我们的目标是集成基于单个字节码的tracing JIT和LLVM的method JIT,以此来获得最好的结果。
基准测试
Pyston更新了基准测试淘金,使用了三个真实的库,分别为pyxl、django、sqlalchemy。基准的选择是一个有争议的话题。但这三个是Python Web服务器中非常典型的。
在这个基准测试中,Pyston比CPython快25%,但比PyPy 4.0.0慢25%。这里有完整的性能跟踪页面,其中含有最新的基础测试结果(说明:后一个链接会随着时间自动更新,且由于配置不同,性能提升的量也会与25%有出入)。
社区
还有若干令人兴奋的消息,虽然这些与Pyston的代码没有直接联系:
- 从Makefile构建系统迁移到基于CMake的构建系统中。这样可以更好的配置、更快的构建(通过ninja)、并降低未来支持其他平台的难度。这由开源贡献者Daniel Agar完成,非常感谢你!
- 添加了更多的文档。Pyston维基页面中含有对Pyston内部工作机制的介绍,以及对新贡献者的一些帮助信息。
- Pyston有了Logo!
- 11个开源贡献者贡献了184个commits。特别感谢孙波翔(译注,也就是我了……),他对Pyston兼容性方面作出很大帮助。
总结
在GitHub上有预编译的二进制Pyston可供下载(不过请阅读使用说明)。Pyston仍然在开发阶段,所以会有崩溃或性能上的问题。如果读者遇到了这些问题,可以在外面的Gitter channel上报告,或发起一个Github issue。我们期待您的反馈!
如果你在湾区,我们在11月10号晚上6点半,在Dropbox旧金山办公地点会有一个研讨会。现在剩余空位不多,如果感兴趣的话可以在这里申请。
Pyston 0.5中同样有许多值得期待的地方。当前的目标是实现最终几个特性(如在推出栈帧退出后进行检查),继续提升性能,以及在Pyston上运行一些Dropbox服务。这是令人兴奋的时刻,同样,我们也期待新的贡献者!如果你有兴趣为Pyston做贡献,可以查看我们的文档,检查开放的issue列表,或仅仅在Gitter中跟我们打个招呼。