为什么PyPy的速度提高了6.3倍,我不应该在Python上使用Pyython呢?

我已经听说了许多关于PyPy项目。 他们声称它比他们网站上的CPython解释器快6.3倍。

每当我们谈论像Python这样的dynamic语言时,速度就是最重要的问题之一。 为了解决这个问题,他们说PyPy比以前快了6.3倍。

第二个问题是并行,臭名昭着的全球口译员锁 (GIL)。 为此,PyPy说它可以给GIL更less的Python 。

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

  1. 正如其他人所说的,PyPy 对C扩展的支持很less 。 它支持,但通常速度比Python慢​​,而且最好也是如此。 因此很多模块只需要 CPython。 Cython和Numpy对于数字来说非常棒 ,而且大多数真正需要Python速度的人都会大量使用那些(+ Pandas,SciPy等)。 由于它们要么是不存在的,要么是得到很less的支持,并且需要快速Python的人速度更慢,而且使用CPython的速度和易用性往往更好
  2. Python 3支持目前是实验性的。 刚刚达到稳定! 截至2014年6月20日, PyPy3 2.3.1 – 支点出局 !
  3. PyPy有时对于“脚本”来说实际上并不快,很多人使用Python。 这些是短小的程序,可以做一些简单而小巧的事情。 由于PyPy是一个JIT编译器,它的主要优点来自长时间运行和简单的types(如数字)。 坦率地说,与CPython相比, PyPy的pre-JIT速度相当糟糕
  4. 惯性 。 转移到PyPy通常需要重新安装,对于某些人员和组织来说,这只是太多的工作。

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

注意:这个问题是古老的! 避免从过时的信息中得出结论。

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

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

这与你所做的全面陈述是完全不同的陈述,当你明白其中的差别时,你至less会理解一个为什么你不能说“使用PyPy”的原因。 这可能听起来像我挑选,但理解为什么这两个声明是完全不同的是至关重要的。

打破这一点:

  • 他们所作的陈述仅适用于他们使用的基准。 它说你的程序绝对没有(除非你的程序和他们的基准程序完全一样)。

  • 该声明是关于一组基准的平均值 。 没有人声称运行PyPy将会使他们testing的程序提高6.3倍。

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

因为pypy不是100%兼容的,需要8个ram来编译,是一个移动的目标,而且是高度实验性的,cpython是稳定的,二十年来模块构build者的默认目标(包括不能在pypy上运行的c扩展),并已被广泛部署。

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

第二个问题更容易回答:如果所有的代码都是纯Python,那么基本上可以使用PyPy作为插件replace。 但是,许多广泛使用的库(包括一些标准库)都是用C语言编写的,并且被编译为Python扩展。 其中一些可以与PyPy一起工作,有些则不行。 PyPy提供了与Python相同的“前向”工具 – 也就是Python–但是它的内部结构是不同的,所以与这些内部接口的工具将不起作用。

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

我认为如果PyPy进入稳定状态,可能会开始得到更广泛的应用。 我也认为,对于Python来说,摆脱C的基础是件好事。 但这一段时间不会发生。 PyPy还没有达到临界点,它几乎可以自己做所有你想做的事情,这将激励人们填补空白。

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

BDFL和CPython开发人员是一群非常聪明的人,并设法帮助CPython在这种情况下performance出色。 这是一个无耻的博客插件: http : //www.hydrogen18.com/blog/unpickling-buffers.html 。 我使用从CPython派生的Stackless,并保留完整的C模块接口。 在这种情况下,我没有发现使用PyPy的好处。

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

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

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

无论PyPy如何解决上述巨大的挑战, 总体而言 ,CPython是一个开放性的问题,在短期内无法解决, 总体而言,速度更快,内存更less,并行性更友好。 有些人认为PyPy将永远无法提供一个通用的解决scheme,使其能够在所有情况下主宰CPython 2.7和3.3。

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


问:为什么现在不能用PyPy替代CPython呢?

答:PyPy与CPython不是100%兼容,因为它不是模拟引擎盖下的CPython。 某些程序可能仍然依赖于CPython在PyPy中不存在的独特function,如C绑定,Python对象和方法的C实现,或者CPython的垃圾收集器的增量性质。

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

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

其他一些软件可以与这两种软件一起工作,但是在CPython中使用更less的内存,因为先前释放了未使用的对象。 (我没有任何测量来表明这是多么重要,以及其他实现细节如何影响内存使用。)

对于很多项目来说,不同的python在速度上实际上有0%的差距。 那些工程时间占主导地位,所有的python都有相同数量的图书馆支持。

为了简单起见,PyPy提供了CPython所缺乏的速度,但牺牲了它的兼容性。 然而大多数人selectPython的灵活性和“电池供电”function(高兼容性),而不是它的速度(尽pipe如此,仍然是首选)。

我find了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运行速度快10倍(!)。 但不是在窗户上。 在那里只有3倍的速度。