763

我听说过很多关于PyPy项目的消息。他们声称它比他们网站上的CPython解释器快 6.3 倍。

每当我们谈论像 Python 这样的动态语言时,速度都是最重要的问题之一。为了解决这个问题,他们说 PyPy 的速度提高了 6.3 倍。

第二个问题是并行性,即臭名昭著的Global Interpreter Lock (GIL)。为此,PyPy 表示它可以提供无 GIL 的 Python

如果 PyPy 能够解决这些巨大的挑战,那么阻碍更广泛采用的弱点是什么?也就是说,是什么阻止了像我这样一个典型的 Python 开发人员现在转向 PyPy ?

4

12 回答 12

706

注意: PyPy 现在比 2013 年被问到这个问题时更成熟,得到更好的支持。避免从过时的信息中得出结论。


  1. PyPy,正如其他人很快提到的那样,对 C 扩展的支持很薄弱。它有支持,但通常速度比 Python 慢,而且充其量也很不稳定。因此,很多模块只需要 CPython。PyPy 不支持 numpy。仍然不支持某些扩展(PandasSciPy等),请在进行更改之前查看支持的软件包列表。请注意,现在支持列表中标记为不支持的许多软件包。
  2. Python 3 支持目前是实验性的。 刚刚达到稳定!截至 2014 年 6 月 20 日,PyPy3 2.3.1 - Fulcrum 已经发布
  3. 对于许多人使用 Python 的“脚本”,PyPy 有时实际上并不快。这些是做一些简单而小的事情的短期程序。因为 PyPy 是一个 JIT 编译器,它的主要优势来自于长时间的运行和简单的类型(例如数字)。与 CPython 相比,PyPy 的 pre-JIT 速度可能很差。
  4. 惯性。迁移到 PyPy 通常需要重新工具,这对于某些人和组织来说简直是太多的工作。

我想说,这些是影响我的主要原因。

于 2013-09-22T17:40:36.580 回答
111

该网站并未声称 PyPy 比 CPython 快 6.3 倍。去引用:

所有基准的几何平均值比 CPython 快 0.16 或 6.3 倍

这是与您所做的一揽子声明非常不同的声明,当您了解其中的区别时,您将理解至少一组您不能只说“使用 PyPy”的原因。听起来我在吹毛求疵,但理解为什么这两个陈述完全不同是至关重要的。

打破它:

  • 他们所做的声明仅适用于他们使用的基准。它绝对没有说明您的程序(除非您的程序与他们的基准测试之一完全相同)。

  • 该声明是关于一组基准的平均值。没有人声称运行 PyPy 会带来 6.3 倍的改进,即使对于他们测试过的程序也是如此。

  • 没有人声称 PyPy 甚至会运行 CPython 运行的所有程序,更不用说更快了。

于 2013-09-22T21:42:22.180 回答
87

因为 pypy 不是 100% 兼容,需要 8 gigs 的 ram 编译,是一个移动的目标,并且是高度实验性的,其中 cpython 是稳定的,模块构建器的默认目标 2 十年(包括不适用于 pypy 的 c 扩展),并且已经广泛部署。

Pypy 可能永远不会成为参考实现,但它是一个很好的工具。

于 2013-09-22T17:27:18.830 回答
40

第二个问题更容易回答:如果您的所有代码都是纯 Python,您基本上可以使用 PyPy 作为替代品。但是,许多广泛使用的库(包括一些标准库)是用 C 编写的,并编译为 Python 扩展。其中一些可以与 PyPy 一起使用,有些则不能。PyPy 提供了与 Python 相同的“前向”工具——也就是说,它是 Python——但它的内部结构不同,因此与这些内部结构交互的工具将不起作用。

至于第一个问题,我想这有点像第一个问题的 Catch-22:PyPy 一直在迅速发展,以提高速度并增强与其他代码的互操作性。这使得它比官方更具实验性。

我认为如果 PyPy 进入稳定状态,它可能会开始得到更广泛的使用。我也认为 Python 摆脱它的 C 基础会很棒。但暂时不会发生。PyPy 还没有达到临界质量,它几乎可以自己做任何你想做的事情,这将激励人们填补空白。

于 2013-09-22T17:31:39.193 回答
15

我在这个主题上做了一个小基准测试。虽然许多其他海报都对兼容性提出了很好的观点,但我的经验是 PyPy 仅在位移动方面并没有那么快。对于 Python 的许多用途,它实际上只存在于在两个或多个服务之间转换位。例如,没有多少 Web 应用程序对数据集执行 CPU 密集型分析。相反,它们从客户端获取一些字节,将它们存储在某种数据库中,然后将它们返回给其他客户端。有时数据的格式会改变。

BDFL 和 CPython 开发人员是一群非常聪明的人,他们设法帮助 CPython 在这种情况下表现出色。这是一个无耻的博客插件:http ://www.hydrogen18.com/blog/unpickling-buffers.html 。我正在使用 Stackless,它源自 CPython,并保留了完整的 C 模块接口。在这种情况下,我没有发现使用 PyPy 的任何优势。

于 2013-09-22T19:02:57.243 回答
14

问:如果 PyPy 与 CPython 相比可以解决这些巨大的挑战(速度、内存消耗、并行性),那么它的哪些弱点阻碍了更广泛的采用?

A:首先,几乎没有证据表明 PyPy 团队可以普遍解决速度问题。长期证据表明,PyPy 运行某些 Python 代码比 CPython 慢,而这个缺点似乎深深植根于 PyPy。

其次,在相当多的情况下,当前版本的 PyPy 比 CPython 消耗更多的内存。所以 PyPy 还没有解决内存消耗的问题。

PyPy 是否解决了上述巨大挑战,并且总体上是否会比 CPython 更快、更少内存占用以及对并行性更友好,这是一个短期内无法解决的悬而未决的问题。有些人打赌 PyPy 永远无法提供一个通用的解决方案,使其能够在所有情况下主宰 CPython 2.7 和 3.3。

如果 PyPy 总体上比 CPython 更好(这是值得怀疑的),那么影响其更广泛采用的主要弱点将是它与 CPython 的兼容性。还有一些问题,例如 CPython 可以在更广泛的 CPU 和操作系统上运行,但与 PyPy 的性能和 CPython 兼容性目标相比,这些问题的重要性要小得多。


问:为什么我现在不能用 PyPy 替换 CPython?

答:PyPy 不是 100% 与 CPython 兼容,因为它没有在底层模拟 CPython。一些程序可能仍然依赖于 CPython 的独特特性,而 PyPy 中没有这些特性,例如 C 绑定、Python 对象和方法的 C 实现,或者 CPython 垃圾收集器的增量特性。

于 2013-09-23T11:32:27.473 回答
11

CPython 有引用计数和垃圾收集,PyPy 只有垃圾收集。

所以对象往往会更早地被删除,并且__del__在 CPython 中以更可预测的方式调用。一些软件依赖于这种行为,因此它们还没有准备好迁移到 PyPy。

其他一些软件可以同时使用这两者,但使用 CPython 使用的内存更少,因为未使用的对象会更早地被释放。(我没有任何测量结果来表明这是多么重要,以及哪些其他实现细节会影响内存使用。)

于 2013-09-22T23:01:58.287 回答
6

对于很多项目来说,不同的 python 在速度方面实际上存在 0% 的差异。那是那些受工程时间支配的那些,并且所有 python 都具有相同数量的库支持。

于 2013-09-23T10:13:36.293 回答
6

为了简单起见:PyPy 提供了 CPython 所缺乏的速度,但牺牲了它的兼容性。然而,大多数人选择 Python 是因为它的灵活性和“包含电池”的特性(高兼容性),而不是它的速度(尽管它仍然是首选)。

于 2014-03-14T00:02:57.100 回答
5

我找到了一些例子,其中 PyPy 比 Python 慢。但是:仅在 Windows 上。

C:\Users\User>python -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 294 msec per loop

C:\Users\User>pypy -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 1.33 sec per loop

因此,如果您想到 PyPy,请忘记 Windows。在 Linux 上,您可以实现出色的加速。示例(列出 1 到 1,000,000 之间的所有素数):

from sympy import sieve
primes = list(sieve.primerange(1, 10**6))

这在 PyPy 上的运行速度比在 Python 上快 10(!) 倍。但不是在窗户上。在那里,它的速度只有 3 倍。

于 2016-10-05T21:32:00.403 回答
4

PyPy 支持 Python 3 已经有一段时间了,但根据Anthony Shaw 于 2018 年 4 月 2 日发表的这篇 HackerNoon 帖子,PyPy3 仍然比 PyPy(Python 2)慢几倍。

对于许多科学计算,尤其是矩阵计算,numpy 是更好的选择(请参阅常见问题解答:我应该安装 numpy 还是 numpypy?)。

Pypy 不支持 gmpy2。你可以改用gmpy_cffi 虽然我没有测试它的速度并且该项目在 2014 年发布了一个版本。

对于 Project Euler 问题,我经常使用 PyPy,from __future__ import division对于我的目的来说,简单的数值计算通常就足够了,但截至 2018 年,Python 3 的支持仍在进行中,最好的选择是在 64 位 Linux 上。截至 2018 年 12 月的最新版本 Windows PyPy3.5 v6.0 处于测试阶段。

于 2018-12-31T00:08:02.507 回答
4

支持的 Python 版本

引用Python 之禅

可读性很重要。

例如,Python 3.8 引入了fstring =

Python 3.8+ 中可能还有其他对您更重要的功能。PyPy 目前不支持 Python 3.8+。

无耻的自我宣传:Python 版本的杀手级功能——如果你想通过使用旧的 Python 版本了解更多你错过的东西

于 2020-03-05T01:16:06.020 回答