《两百万前素数之和与前两百万素数之和》中,我们用Python求了前两百万的素数和以及两百万前的素数和,并且得到了在Python 3.3中的执行时间如下:

两百万前的素数之和:
142913828922
time: 2.4048174478605646

前两百万的素数之和:
31381137530481
time: 46.75734807838953

于是想办法提高python脚本的执行效率,我觉得在算法方面,优化空间已经比较小了,于是考虑执行器上的优化。在搜索的无意间我看到了一个名词——Psyco!这是python的一个外部模块,导入后可以加快.py脚本的执行。网上也有《用 Psyco 让 Python 运行得像 C一样快》、《利用 psyco 让 Python 程序执行更快》之类的文章,说明Psyco确实是一个可行的选择,于是就跃跃欲试了,后来了解到Psyco在2012年已经停止开发,只支持到Python 2.4版本,目前它由 PyPy所接替。于是我就下载了PyPy

PyPy不再是一个python的外部模块,而是一个独立的解析器了,也就是说我们可以用pypy prime.py的命令执行.py脚本,它目前是基于python 2.7.6的,有windows版本。效率如何呢?请看

两百万前的素数之和:
142913828922
('time:', 0.226615647130835)

前两百万的素数之和:
31381137530481
('time:', 9.033084048872064)

一个从2.4秒缩短为0.3秒,一个由47秒缩短为9秒,速度提高了好几倍!这两个脚本用Pypy执行确实让人满意~

那是不是所有的python脚本都可以改为由pypy执行呢?不一定。有不少例子还是在Python运行得比较快,比如下面求$10000!$的脚本(只计算,不输出)

import time
start=time.clock()
s=1
for i in range(1,10000+1):
    s=s*i

end=time.clock()
print(end-start)

在Python 3.3中只需要0.06秒,在PyPy中却要0.3秒。如果求$100000!$,PyPy花了39秒,而Python 3.3只用了7秒!

关于PyPy和Python,下面是来自Veedrac的最佳答复

就像其他人提到的,PyPy有很弱的C语言扩展性。它支持C语言扩展,但是比Python本身的速度还慢。因此,很多模块本身就要求使用CPython。

CPython 上的Numpy的数据处理性非常好,满足了那些既要求速度又大量使用Pandas, SciPy等数据分析任务的库的人。

所以,Pypy 要么不支持或者很弱支持C语言扩展,要么减慢了那些数据处理的速度。完全无法比拟既可以满足速度要求又简单易用的CPyhon。

第二点,Python 3的支持在现阶段还是实验期。那些使用最新版本的Python新功能的人,现在应该还不愿意扔掉那些还在新鲜期的新奇功能。

第三点,PyPy 并不是真正的脚本快,而大多数使用Python 的人就是在用脚本。这些脚本就是一些简短的程序。 PyPy 的最大优点是它针对长时间运行的简单数字处理的即时 (JIT) 编译器。直白地说, PyPy的先编译处理时间比CPython长的多。

第四点,惰性。转移到PyPy需要重新装备机器. 这对很多用户或者使用机构来说,都是太多的额外工作了。

但是对于笔者来说,我目前主要的编程是有大量重复计算的科学计算程序,PyPy确实可以大大提高效率!所以以后可能会尽量多使用PyPy执行的。

转载到请包括本文地址:https://kexue.fm/archives/2621

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

如果您需要引用本文,请参考:

苏剑林. (Jun. 11, 2014). 《用PyPy提高Python脚本执行效率 》[Blog post]. Retrieved from https://kexue.fm/archives/2621

@online{kexuefm-2621,
        title={用PyPy提高Python脚本执行效率},
        author={苏剑林},
        year={2014},
        month={Jun},
        url={\url{https://kexue.fm/archives/2621}},
}