首页 > 代码库 > 初用Cython编写扩展模块

初用Cython编写扩展模块

    这篇博文还是讲关于提高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函数。


初用Cython编写扩展模块