python作为一门强大的脚本语言,优势自然不必说。但是,当我们的模型较复杂,运算量较大的时候,python的短板就会出现,就是运算速度慢。当然,解决这一问题有很多方法,比如pypy的jit技术,但是抛开稳定性不提,使用pypy有很多限制,而且不是那么工程化。所以,向大家介绍Cython,方便将别的应用场景中的一些重计算的部分单独取出来,然后用Cython改写,独立成模块来提高运算速度。
首先,大家都知道,C语言是编译性语言,而Python则是解释性语言,简而言之,就是Python运行是逐行运行,不需要实现编译,而C需要在运行前编译。那么,可想而知,如果运行前,需要事先编译,那么其实有一种“上帝视角”的感觉,自然可以做很多优化,让代码运行的更快。而Cython的出现就是这个目的,让Python也可以被编译,然后执行。Cython是一种部分包含和改变C语言,以及完全包含pyhton语言的一个语言集合。Cython是用Python实现的一种语言,可以用来写Python扩展,用它写出来的库都可以通过import来载入,性能上比Python的快。Cython里可以载入Python扩展(比如 import math),也可以载入C的库的头文件(比如:cdef extern from “math.h”),另外也可以用它来写Python代码。将关键部分重写成C扩展模块。Cython中的强大之处在于可以把Python和C结合起来,它使得看起来像Python语言的Cython代码有着和C相似的运行速度。
首先我们要知道,cython的文件后缀是.cyx,而且既然cython是python语言的一个超集,那么,cyx里面运行纯python文件也是没有问题的了。pyx文件只是Cython源代码文件,要想被python调用运行,还要转成c\c++的文件,再进一步转成.pyd文件(window系统)或者.so文件(Linux系统)。.pyd和.so文件才是可以直接在python文件中import使用的文件。
编译经过两个阶段:
* Cython编译.pyx文件为.c文件;
* C编译器会把.c文件编译成.so文件(Linux系统)或者.pyd文件(Windows系统);
我们新建一个hello.pyx文件,在里面输入:
def hello():
print ("Hello World")
没有任何特殊,然后我们新建一个setup.py脚本,这个python文件的目的就是使用cython编译器去编译pyx折一个cython文件。setup.py文件的代码很简单:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("hello.pyx")
)
然后我们运行一下setup.py文件:
python setup.py build_ext --inplace. build_est
大概就是编译extension文件的意思,inplace则是放到源代码pyx旁边,也就是同一目录下的意思。然后,我们就可以看到多了两个文件,一个是hello.c一个是hello.so(Linux系统)或者hello.pyd(windows系统)。这里,c文件就是cython将我们的pyx文件解析成一个c文件件,不依赖与平台,而后面的so或者pyd文件,则是将c文件进行编译后的一个文件,依赖于平台。这个时候,so文件或者pyd文件就可以像普通的python文件一样,被import。