PyPy如何比Cpython更快

Ran*_*dra 4 pypy

我读过PyPy - 它怎么可能击败CPython?还有无数其他的东西,但我无法理解用Python编写的东西比python本身更快.

我能想到的唯一方法是PyPy以某种方式绕过C并直接编译成汇编语言指令.如果是这样,那就没关系了.

有人可以向我解释PyPy是如何工作的吗?我需要一个简单的答案.

我喜欢python,并希望开始贡献.PyPy看起来像一个很棒的起点,无论他们是否拉我的代码.但我无法理解我所做的简短研究.

Ben*_*Ben 13

理解PyPy的最简单方法是忘记它是用Python实现的.

实际上它不是,它是在RPython中实现的.RPython可以使用Python解释器运行,但是Python代码无法由RPython编译器(PyPy转换框架)编译.RPython是Python的一个子集,但是"遗漏"的部分足够实用,RPython中的编程与Python中的编程非常不同.

因此,由于Python代码不能被视为RPython代码,并且惯用的RPython程序"外观和感觉"与惯用的Python程序非常不同,所以让我们忽略它们之间的连接,并考虑一个简单的例子.

假装我用编译器开发了一种新语言Frobble.我在Frobble写了一个Python解释器.我声称我的"FrobblePython"解释器通常比CPython解释器快得多.

这会让你觉得奇怪或不可能吗?当然不是.新的Python解释器可以比CPython解释器更快或更慢(或者更有可能,在某些事情上更快,在其他事情上更慢,通过改变边距).它是否更快将取决于FrobblePython的实现,以及我的Frobble编译器编译的代码的性能特征.

正是你应该如何思考PyPy解释器的原因.用于实现它的语言RPython碰巧能够被Python解释器解释(具有与编译RPython程序相同的外部结果并运行它)理解它的速度完全无关.重要的是PyPy解释器的实现,以及RPython编译器编译的代码的性能特征(例如RPython编译器可以自动为它编译的程序添加某些类型的JITing功能).


小智 6

"它有一个JIT"答案在技术上是正确但不充分.PyPy作为Python代码运行,由Python解释器,可以JIT编译解释的Python代码(事实上​​,JIT测试通常以这种方式运行)但仍然非常慢(可能需要几分钟才能开始解释).

缺少的部分(早于JIT并且实际上是JIT所需的)是在Python的一个受限子集(称为RPython)中编写解释器,然后将其编译为C代码.通过这种方式,您可以获得一个大致在C抽象级别运行的程序(尽管被编写为更高级别的抽象).这个解释器在历史上是,并且AFAIK仍然比CPython慢​​一些,但不会慢几个数量级(如解释翻译所示).

您对"直接汇编到汇编"的评论表明了混淆.汇编代码不会自动快于C代码 - 事实上,你很难在生成汇编代码时击败今天的C编译器,并且C代码更容易编写和/或生成,即使没有进入整个可移植性一塌糊涂.问题不在于将Python变成C或汇编(看看Nuitka),问题是在不影响语义的情况下以更有效的方式解释程序.直接进行汇编并没有解决任何难题,使得为更高效的程序生成代码的相对容易的问题更难,并且很少允许您在C中无法表达的任何优化.

现在,PyPy的JIT确实生成了机器代码,但PyPy可执行文件是由C编译器从C代码编译的.如果他们试图在一个平台上与现有的C编译器竞争,那么PyPy开发人员将是白痴,更不用说多个平台了.幸运的是,他们不是白痴,而且知道这一点.为让JIT生成汇编代码的原因是不同的,更好的(对于初学者来说,在JIT的背景下出现一些优化,你也不会在C做的).

顺便说一下,我上面写的大部分内容也在你链接到的问题的答案中说明.