【问题标题】:How can PyPy be faster than CpythonPyPy 怎么比 Cpython 快
【发布时间】:2012-09-28 18:27:01
【问题描述】:

我已经阅读了PyPy -- How can it possibly beat CPython? 和无数其他的东西,但我无法理解用 Python 编写的东西如何比 python 本身更快。

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

有人可以向我解释 PyPy 的工作原理吗?我需要一个简单的答案。

我喜欢 python 并想开始贡献。无论他们是否拉取我的代码,PyPy 看起来都是一个很棒的起点。但我无法从我所做的简短研究中理解。

【问题讨论】:

    标签: pypy


    【解决方案1】:

    理解 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 能力)。

    【讨论】:

      【解决方案2】:

      “它有 JIT”的答案在技术上是正确的,但还不够。 PyPy 作为 Python 代码运行,通过 Python 解释器,可以 JIT 编译 Python 代码 it 解释(事实上,JIT 测试经常以这种方式运行)但仍然非常慢(可能需要几分钟只是开始解释)。

      在 JIT 之前并且实际上是 JIT 所需的缺失部分是在 Python 的受限子集(称为 RPython)中编写解释器,然后将其编译为 C 代码。这样,您将获得一个运行在大致 C 抽象级别的程序(尽管被编写为更高的抽象级别)。这个解释器在历史上和 AFAIK 仍然比 CPython 慢一些,但不会慢几个数量级(就像解释器那样)。

      您关于“直接编译为汇编”的评论暴露了混乱。汇编代码不会自动比 C 代码快——事实上,你很难在生成汇编代码方面击败当今的 C 编译器,而且 C 代码更容易编写和/或生成,即使没有进入整个可移植性混乱。问题不在于将 Python 转换为 C 或汇编(看看 Nuitka),问题在于以更有效的方式解释程序而不影响语义。直接进行汇编并不能解决任何难题,使为更高效的程序生成代码的相对简单的问题变得更加困难,并且很少允许您无法用 C 表达的任何优化。

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

      顺便说一句,我上面写的大部分内容也都在您链接到的问题的答案中说明了。

      【讨论】:

        【解决方案3】:

        PyPy 本身是用 RPython 编写的,它是 Python 的一个受限子集。虽然您可以在 CPython 之上运行它,但它非常慢,因此您可以将这个 RPython 翻译成 C,从而绕过解释。从理论上讲,这已经可以比 CPython 快,但实际上要慢很多。除此之外,还实现了一个即时编译器(也在 RPython 中),它将 Python 编译为汇编器。

        简而言之,在运行时的任何时间点都不涉及实际的双重解释,因此没有问题。

        【讨论】:

          【解决方案4】:

          Pypy 具有 JIT(即时)编译功能。 JIT 编译可以在运行时进行优化(因为它没有预编译)。

          代码不会从一开始就编译为汇编或 C。它是解释代码(在 Pypy 解释器中运行)。然后解释器可以“即时”进行编译。

          http://en.wikipedia.org/wiki/Just-in-time_compilation

          http://en.wikipedia.org/wiki/Interpreted_language

          【讨论】:

          • 复杂的东西人。如果我要尝试这样的事情,我真的需要学习很多东西
          • Pypy 为您做所有事情。大多数 python 代码,您将能够在 Pypy 中运行它。我认为你现在为 Pypy 做贡献是不合理的。从获得所需的技术知识开始;这可能是一个漫长的过程。
          • @fijal 解释一下。因为答案是正确的,并且只说明 Pypy 使用了即时编译。其他答案提供了更多细节。
          • 我实际上并不确定我的意思。完全误读帖子的机会很高。接受我的道歉(我也删除了评论)
          猜你喜欢
          • 2011-10-27
          • 1970-01-01
          • 2013-09-27
          • 2019-06-14
          • 1970-01-01
          • 2018-03-02
          • 1970-01-01
          • 1970-01-01
          • 2019-12-16
          相关资源
          最近更新 更多