我一直听说PyPy项目。他们声称在他们的网站上,它比CPython解释器快6.3倍。
每当我们谈到像Python这样的动态语言时,速度是最重要的问题之一。为了解决这个问题,他们说PyPy比较快6.3倍。
第二个问题是并行性,臭名昭著的全局解释器锁定(GIL)。对此,PyPy表示它可以提供无GIL Python。
如果PyPy能够解决这些巨大的挑战,那么是什么阻止了它的广泛采用呢?也就是说,是什么阻止了像我这样的典型Python开发人员立即切换到PyPy呢?
我一直听说PyPy项目。他们声称在他们的网站上,它比CPython解释器快6.3倍。
每当我们谈到像Python这样的动态语言时,速度是最重要的问题之一。为了解决这个问题,他们说PyPy比较快6.3倍。
第二个问题是并行性,臭名昭著的全局解释器锁定(GIL)。对此,PyPy表示它可以提供无GIL Python。
如果PyPy能够解决这些巨大的挑战,那么是什么阻止了它的广泛采用呢?也就是说,是什么阻止了像我这样的典型Python开发人员立即切换到PyPy呢?
这些是我认为对我产生影响的主要原因。
np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)
?),这使得Python非常适合科学界。此外,在Python中处理不太密集的部分并将其转换为C语言以处理更小的密集循环是一种常见而可行的策略。 - Veedrac该网站并未声称PyPy比CPython快6.3倍。引用原话:
所有基准测试的几何平均值为0.16,比CPython快6.3倍
这是一种非常不同的说法,当你理解了它们之间的区别时,你就会明白至少一个不能仅仅说“使用PyPy”的原因。这可能听起来像我在挑剔,但是理解这两个声明为什么完全不同是至关重要的。
具体说明如下:
他们所说的只适用于他们使用的基准测试。除非你的程序与他们的基准测试完全相同,否则它对你的程序没有任何意义。
这个声明是关于一组基准测试的平均值。并没有声称运行PyPy即使对于他们测试的程序而言也会有6.3倍的提升。
并没有声称PyPy可以运行CPython所有程序,更别说比CPython更快了。
由于pypy不完全兼容,编译需要8GB内存,是一个不断更新的实验性工具,而cpython则是稳定的默认目标,已成为模块构建者2十年来的首选(包括不适用于pypy的c扩展),并已广泛部署。
pypy很可能永远不会成为参考实现,但它是一个不错的工具。
我对这个话题进行了小小的基准测试。虽然其他许多帖子中提出了很多有关兼容性的好观点,但我的经验是,PyPy在仅移动位时并不比其他解释器快很多。对于 Python 的许多用途,它实际上只存在于两个或多个服务之间传输位。例如,很少有 Web 应用程序执行 CPU 密集型数据集分析。相反,它们从客户端获取一些字节,将其存储在某种数据库中,稍后将其返回给其他客户端。有时数据的格式会发生变化。
BDFL 和 CPython 开发人员是一群非常聪明的人,他们已经成功地帮助 CPython 在这种情况下表现出色。这里插一下博客链接: http://www.hydrogen18.com/blog/unpickling-buffers.html。我正在使用源自 CPython 并保留完整的 C 模块接口的 Stackless。在那种情况下,我没有发现使用 PyPy 有任何优势。
问:如果与CPython相比,PyPy可以解决这些巨大的挑战(速度、内存消耗、并行性),那么它的弱点是什么,阻止了更广泛的采用?
答:首先,很少有证据表明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与CPython不是100%兼容,因为它并没有在底层模拟CPython。一些程序可能仍然依赖于CPython的独特功能,这些功能在PyPy中不存在,比如C绑定、Python对象和方法的C实现,或者CPython垃圾回收器的增量特性。
CPython有引用计数和垃圾回收机制,而PyPy只有垃圾回收机制。
因此,在CPython中对象往往更早被删除,并以更可预测的方式调用__del__
方法。一些软件依赖于这种行为,因此它们还没有准备好迁移到PyPy。
另一些软件可以同时使用两者,但使用CPython可以节省更多内存,因为未使用的对象会更早地被释放。(我没有任何测量数据来表明这有多重要,以及其他实现细节如何影响内存使用。)
__del__
被早期或根本不会被调用是错误的。就像你所说,“通常”情况下可以工作,有些人认为这意味着它是保证的。如果任何引用该对象的内容都被包含在引用循环中(这相当容易 - 你知道以某种非假设方式检查当前异常会创建一个引用循环吗?),最终化将无限期地延迟,直到下一个循环GC(可能会永远延迟)。如果该对象本身是引用循环的一部分,则在Python 3.4之前根本不会调用__del__
。 - user395760对于许多项目而言,在工程时间占主导且所有Python版本都拥有相同数量的库支持的情况下,实际上不同的Python版本在速度方面没有任何区别。
我发现有些例子中,PyPy在Windows上比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 倍!但是在 Windows 上并不是这样。在那里,速度只能提高 3 倍。