277

来自谷歌开源博客

PyPy 是 Python 中 Python 的重新实现,它使用先进的技术来尝试获得比 CPython 更好的性能。多年的努力终于有了回报。我们的速度结果经常超过 CPython,范围从稍微慢一点,到实际应用程序代码的最高加速 2 倍,再到小型基准测试的最高 10 倍加速。

这怎么可能?使用哪个 Python 实现来实现 PyPy?CPython ? PyPyPy 或 PyPyPyPy 击败他们的分数的机会有多大?

(在相关说明中......为什么有人会尝试这样的事情?)

4

4 回答 4

309

“PyPy 是 Python 中 Python 的重新实现”是描述 PyPy 的一种相当误导的方式,恕我直言,尽管它在技术上是正确的。

PyPy 有两个主要部分。

  1. 翻译框架
  2. 口译员

翻译框架是一个编译器。它将RPython代码编译为 C(或其他目标),自动添加垃圾收集和 JIT 编译器等方面。它不能处理任意 Python 代码,只能处理 RPython。

RPython 是普通 Python 的子集;所有 RPython 代码都是 Python 代码,但不是相反。RPython 没有正式的定义,因为 RPython 基本上只是“可以被 PyPy 的翻译框架翻译的 Python 的子集”。但是为了被翻译,RPython 代码必须是静态类型的(类型是推断出来的,你不需要声明它们,但它仍然是每个变量严格的一种类型),你不能做诸如声明/修改函数之类的事情/运行时的类。

解释器是一个用 RPython 编写的普通 Python 解释器。

因为 RPython 代码是普通的 Python 代码,所以您可以在任何 Python 解释器上运行它。但是 PyPy 的速度声明都不是来自于以这种方式运行。这只是为了快速测试周期,因为翻译解释器需要很长时间

了解了这一点后,关于 PyPyPy 或 PyPyPyPy 的猜测实际上没有任何意义。你有一个用 RPython 编写的解释器。你把它翻译成可以快速执行 Python 的 C 代码。过程在那里停止;没有更多的 RPython 可以通过再次处理来加速它。

所以“PyPy 怎么可能比 CPython 更快”也变得相当明显。PyPy 有一个更好的实现,包括一个 JIT 编译器(我相信,如果没有 JIT 编译器,它通常不会那么快,这意味着 PyPy 只对易受 JIT 编译影响的程序更快)。CPython 从未被设计为 Python 语言的高度优化实现(尽管他们确实试图使其成为高度优化的实现,如果你遵循不同之处的话)。


PyPy 项目的真正创新之处在于他们不用手工编写复杂的 GC 方案或 JIT 编译器。他们在 RPython 中相对简单地编写解释器,并且对于所有 RPython 比 Python 低级,它仍然是一种面向对象的垃圾收集语言,比 C 高级得多。然后翻译框架会自动添加诸如 GC 和 JIT 之类的东西。所以翻译框架是一个巨大的努力,但它同样适用于 PyPy python 解释器,但是它们改变了它们的实现,允许更多的实验自由来提高性能(不用担心引入 GC 错误或更新 JIT 编译器以应对这些变化)。这也意味着当他们开始实现 Python3 解释器时,它会自动获得相同的好处。以及使用 PyPy 框架编写的任何其他解释器(其中有许多处于不同的抛光阶段)。并且所有使用 PyPy 框架的解释器都会自动支持框架支持的所有平台。

因此,PyPy 项目的真正好处是(尽可能地)分离出为动态语言实现高效的平台无关解释器的所有部分。然后在一个地方提出一个很好的实现,可以在许多解释器中重复使用。这不是像“我的 Python 程序现在运行得更快”那样的立竿见影的胜利,但它对未来是一个很好的前景。

它可以更快地运行你的 Python 程序(也许)。

于 2012-01-10T02:07:14.383 回答
161

Q1。这怎么可能?

在某些情况下,手动内存管理(这是 CPython 对其计数所做的)可能比自动管理慢。

CPython 解释器实现的限制排除了 PyPy 可以做的某些优化(例如细粒度锁)。

正如马塞洛所说,JIT。能够即时确认对象的类型可以节省您进行多次指针取消引用以最终到达您想要调用的方法的需要。

Q2。使用哪个 Python 实现来实现 PyPy?

PyPy 解释器是在 RPython 中实现的,它是 Python 的静态类型子集(语言而不是 CPython 解释器)。- 有关详细信息,请参阅https://pypy.readthedocs.org/en/latest/architecture.html

Q3。PyPyPy 或 PyPyPyPy 击败他们的分数的机会有多大?

这将取决于这些假设解释器的实现。例如,如果其中一个获取源代码,对其进行某种分析,并在运行一段时间后将其直接转换为特定目标的汇编代码,我想它会比 CPython 快得多。

更新:最近,在一个精心设计的示例中,PyPy 的性能优于使用gcc -O3. 这是一个人为的案例,但确实展示了一些想法。

Q4。为什么有人会尝试这样的事情?

来自官方网站。https://pypy.readthedocs.org/en/latest/architecture.html#mission-statement

我们的目标是提供:

  • 用于生成动态语言实现的通用翻译和支持框架,强调 语言规范和实现 方面之间
    的清晰分离。我们称之为_。

    RPython toolchain

  • Python_ 语言的兼容、灵活和快速的实现,它使用上述工具链来启用新的高级高级功能,而无需对低级细节进行编码。

通过以这种方式分离关注点,我们的 Python 和其他动态语言的实现能够自动为任何动态语言生成即时编译器。它还允许对实现决策采用混合搭配的方法,包括许多历史上不受用户控制的决策,例如目标平台、内存和线程模型、垃圾收集策略以及应用的优化,包括是否具有首先是 JIT。

C 编译器 gcc 是用 C 实现的,Haskell 编译器 GHC 是用 Haskell 编写的。你有什么理由不使用 Python 编写 Python 解释器/编译器吗?

于 2010-04-07T11:48:51.563 回答
24

PyPy 是用 Python 实现的,但它实现了一个 JIT 编译器来动态生成本机代码。

在 Python 之上实现 PyPy 的原因可能是它只是一种非常高效的语言,特别是因为 JIT 编译器使得宿主语言的性能有些无关紧要。

于 2010-04-07T11:17:56.513 回答
12

PyPy 是用受限 Python 编写的。据我所知,它并不在 CPython 解释器之上运行。受限 Python 是 Python 语言的一个子集。AFAIK,PyPy 解释器被编译为机器代码,因此在安装时它不会在运行时使用 python 解释器。

您的问题似乎期望 PyPy 解释器在执行代码时在 CPython 之上运行。 编辑:是的,要使用 PyPy,您首先将 PyPy python 代码转换为 C 并使用 gcc 构建、jvm 字节代码或 .Net CLI 代码。请参阅入门

于 2010-11-19T03:58:23.840 回答