这篇博文还是讲关于提高Python运行效率的,这确实是一个值得去仔细研究一番的问题,这篇博文介绍完Cython后,还要接着介绍线程、进程和协程在提高Python代码运行效率起着怎样的作用,那么我的这个系列的博文基本上写完了。
首先要介绍一下各种*ython,太多了,什么python,pypy呀,等等,都是什么呢。这里简单的做个介绍。
CPython:这是平时用的最广泛的,是用C语言实现的解释器,平时说的Python一般都是指CPython。
Jython:用Java实现的的python解释器。
IronPython:用C#实现的python解释器。
RubyPython:用Ruby实现的Python解释器。
Brython:用Javascript实现的Python解释器。
PyPy:用rPython(是Python的一个子集)实现的python解释器。
Cython: 一个Python的超集,能够调用C语言的函数,允许你为你的Python代码写C扩展,允许你为 你 的 Python代码加入静态类型,运行编译并达到接近C语言的性能。
IPython:跟其他版本完全不一样,这是一个Python的计算环境。为一些GUI工具集和浏览器体验等提供 支 持。
Psyco:已经停止维护了,发展成为现在的PyPy了。
PyObjc:Python和Objective-C语言直接的桥梁。这意味着能在你的Python代码中使用Objective-C 的 库(包括创建一个OS X应用程序所需要的一切),反过来在Objective-C里面也可以使用 Python的模块。
PyQt::同PyObjc帮你绑定OS X GUI组件类似,PyQt帮你绑定Qt应用程序框架,让你可以创建丰富的 图 形界面,访问关系数据库等等。
pyjs (Pyjamas): Python中一个创建web和桌面应用程序的框架。包含一个Python-to-JavaScript的编 译 器和其他一些工具。
Python 3000 (Py3k):Python 3.0的一个别名,2008年释出的一个主要版本,但是它并不向后兼容。
下面开始介绍Cython吧。前两篇博文介绍了利用Python对外接口,使用C/C++来提高运行效率(参见博文《初用C/C++扩展Python,提高性能》和《再探C/C++扩展Python》)。但是有个问题,对于对C/C++使用不是很熟练的人(比如我,虽然懂C和C++,但用的也是不是很熟练呀),用这种方法的话,费时又费力,就在这个时候Cython出现了,它可以把Python代码直接编译成C/C++代码,从而获得性能上的提升。
第一步肯定是安装,安装很简单,用pip安装,一条命令就可以搞定。
sudo pip install -U cython
如果想知道它怎么用,打开终端,输入cython,就会有相关命令帮助。如下图:
看看,它的命令相关的用法都已经告诉了,在此我就不过多介绍了,英文不好的,可以用谷歌翻译,一般都是可以理解的了的。下面随便写个python代码试用一下。代码如下:
#coding=utf-8 def is_primenumber(n): if n <= 1: return False if n == 2: return True if n == 3: return False for i in xrange(2,n//2 + 1): if n % i == 0: return True return False
还是判读一个正整数是不是素数,文件名为good.py。根据上图中cython命令使用方法,打开终端,切换到文件所在目录,执行如下命令
cython good.py
然后就在当前目录生成一个名为good.c的文件,当然你也可以自己指定路径及文件名。根据上图的命令使用方法提示,我们可以用参数o。如下:
cython good.py -o /home/liuonghua/good1.c
那么会将good.py编译成为等价的c/c++代码会拷贝到/home/liulong/目录下的good1.c文件下(如果该文件不存在会自动创建)。我们可以打开这个good.c文件看看,3000多行呀,一个只有十五六行的Python代码被编译成了3000多行的C/C++代码。那怎么在这3000多行代码中找到对应的用Python代码写的代码呀?在文件里搜索“is_primenumber”,可以找的到,由于代码比较长,在此不贴了,至于cython将python代码编译成c/c++代码的机理是什么,有时间研究一番后再和大家分享我的学习经验。
竟然以及被编译成立.c文件,那么接下来的操作和上篇博文《初用C/C++扩展Python,提高性能》一样,将它编译成.so文件(怎么编译,可参考上篇博文),然后拷贝到python2.7/dist-packages目录下,然后就可以利用该模块了。在此不过多阐述,直接贴上我的测试运行效率的结果结果。
代码如下:
#coding=utf-8 from good import is_primenumber import datetime def is_prime(n): if n <= 1: return False if n == 2: return True if n == 3: return False for i in xrange(2,n//2 + 1): if n % i == 0: return True return False t0 = datetime.datetime.now() a = is_prime(10) t1 = datetime.datetime.now() b = is_primenumber(10) t2 = datetime.datetime.now() print t2-t1,t1-t0
结果如下:
性能是不是提高了很多。今天就介绍到这儿,明天在介绍Cython直接调用c函数。