编译器级加速器:Pypy使用 | Hom

编译器级加速器:Pypy使用

PyPy是一个独立的解析器, 通过即时编译( JIT,Just-in-time)代码避免逐行解释执行来提升运行速度的(将编译过的行代码缓存起来,从而加快速度)。我们一般使用的Python一般是使用C实现的,为了和其余解析器区分一般又叫CPython.

安装:

Win

直接官网下载安装就好了 link

Mac安装:

   brew install pypy
#brew install pypy

# Then appear:

# A "distutils.cfg" has been written to:
#   /usr/local/Cellar/pypy/2.6.1/libexec/lib-python/2.7/distutils
# specifying the install-scripts folder as:
#   /usr/local/share/pypy
# 
# If you install Python packages via "pypy setup.py install", easy_install_pypy,
# or pip_pypy, any provided scripts will go into the install-scripts folder
# above, so you may want to add it to your PATH *after* /usr/local/bin
# so you don't overwrite tools from CPython.
# 
# Setuptools and pip have been installed, so you can use easy_install_pypy and
# pip_pypy.
# To update setuptools and pip between pypy releases, run:
#     pip_pypy install --upgrade pip setuptools

安装外部库

由于pypy是独立的解析器,所以不能使用python中的外部库如numpy等.需要额外安装.

一般的库,使用pypy提供的相应版本工具 easy_install_pypy, pip_pypy安装即可.

其中NumPy需要安装其提供的版本:

   # 直接pip安装
pypy -m pip install git+    https://bitbucket.org/pypy/numpy.git
# 或以下方式:
git clone     https://bitbucket.org/pypy/numpy.git
cd numpy
pypy setup.py install

要使用numpy,官方还是建议使用numpy on CPython.

测试

C算例:

   #include 

int fib(int n){
   if (n < 2)
     return n;
   else
     return fib(n - 1) + fib(n - 2);
}
 
int main() {
    printf("%d",fib(40));
    return 0;
}

Python算例:

   #! /usr/bin/env python

def fib(n):
    if n < 2:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

print fib(40)

Test 结果(Mac上)

   # Normal Python 2.7.8
$ time python hi.py
102334155
python hi.py  49.72s user 0.21s system 98% cpu 50.844 total
# PyPy 2.6.1 on 2.7.10
$ time pypy hi.py
102334155
pypy hi.py  2.93s user 0.09s system 91% cpu 3.299 total
# gcc 
$ time ./testC
102334155 
./testC  0.92s user 0.00s system 99% cpu 0.932 total

由上例可以知道C的效果最快了.而Pypy明显比原python解析器快得多.原因是即时编译后直接反复递归时加速了.

但Pypy也不一定能提速..如以下的例子耗时在循环当中,并不涉及什么数据结构和即时编译加速的问题.相反,速度还更慢了.

Python算例2:

   import time
start=time.clock()
s=1
for i in range(1,100000+1):
    s=s*i
end=time.clock()
print("Cost Time:",end-start)

结果:

   # Python
$ time python hihi.py
('Cost Time:', 3.6729230000000004)
python hihi.py  3.67s user 0.03s system 99% cpu 3.712 total

# PyPy
$ time pypy hihi.py
('Cost Time:', 4.259539)
pypy hihi.py  3.17s user 1.17s system 99% cpu 4.365 total

Veedrac的一个答复Python和Pypy区别:

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

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

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

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

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

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

可见,针对C扩展Python还是要比PYPY好的,因此做数据分析的话,Python还是更好一些.然而要是不调用numpy一类的库时,只是自己去做一些耗时的数字运算和反复调用到某些函数/类时,pypy还是很有优势的,尤其程序较大时.

Psyco

Psyco可以说是Pypy的前身了,可惜已经不维护挂了(好像最多支持到python2.4).和Pypy直接用编译器加速不同,他是通过加载外部库然后实现加速的,可以直接被Python使用.如果要试用Psyco,可参考以下代码安装试用:

   sudo apt-get install python-psyco

python脚本中开始时加入一段调用即可:

   try:
	import psyco;
	psyco.full()
except ImportError:
	pass; # psyco not installed so continue as usual

Reference

  1. Pypy
  2. Psyco-SF
  3. Python编程规范及性能优化(好文)
  4. Python性能优化的20条建议

你可能感兴趣的:(编译器级加速器:Pypy使用 | Hom)