什么情况?Python运行速度居然追上了C语言!

在小编所从事的IT行业中,程序猿们普遍的感受就是越高级的编程语言越简单(如Python),相反,越低级的编程语言越复杂(如C语言)。其实他们各有优缺点,Python简单;但是运行慢,C语言虽然复杂,但是运行很高效。很多人喜欢高级语言编程,是因为高级语言语法简单,编程高效,用Python通常几十行代码就能做到C语言几百行才能做到的事情。那么我们有没有办法能够既用Python编程并且运行效率又能无限接近C语言呢?

答案是肯定的,那就是--Cython。接下来,我们来具体了解一下Cython这个东东。

Cython介绍

我们知道,Python作为一门高级编程语言,除了编码简单外,还有Python是一门脚本语言,代码不需要经过编译即可运行。在这里为了提高Python的运行效率,我们通过Cython将.py文件生成.c文件,然后将.c文件作为Python源码的一部分,重新编译生成Python模块,使用时直接import即可。所以通俗的说Cython就是Python编程语言的编译器,写C扩展就像写Python代码一样容易。其最重要的功能是将Python代码翻译为C代码

接下来我们具体来说一说这个工具,首先我们得搭建环境(以win7系统为例)。

Cython环境搭建

1、前提条件
我们默认win7系统已经安装了Python,如果没有安装Python,请到Python官网https://www.python.org/downloads/这个地址下载安装。

2、在安装完成Python之后,打开windows命令控制台,输入“python --version”,我们能够看到如下图所示:

什么情况?Python运行速度居然追上了C语言!

如果是如下图:

什么情况?Python运行速度居然追上了C语言!

有可能是因为python.exe文件在 Python 目录下,我们还没有设置环境变量。所以我们需要手动添加环境变量:鼠标右键我的电脑  -> 属性 -> 点击高级系统设置 -> 点击环境变量 -> 点击PATH -> 在最后面加上我们的Python安装路径 -> 点击确定。用一张图来表示就是:

什么情况?Python运行速度居然追上了C语言!

设置完成继续输入“python --version”就可以看到图一的画面啦。

3、同样的方法输入“cython --version”,如果没有安装,则输入如下安装命令“pip install cython”,如下图:

什么情况?Python运行速度居然追上了C语言!

如果连pip都没有安装的话,我们同样需要在Python的官网上先下载pip,下载地址是:https://pypi.python.org/pypi/pip#downloads
如下图:

什么情况?Python运行速度居然追上了C语言!

Cython使用

前面我们把环境搭建好了,现在我们正式体验下这个功能。小编我在电脑下随机创建了一个hello.py的文件,内容如下:

def say_hello():
    print "hello world"

然后在同一目录下,新建一个setup.py文件,内容如下:

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize("hello.py"))

说明:
cythonize()是Cython提供将Python代码转换成C代码的API。
setup是Python提供的一种发布Python模块的方法。

接下来我们编译python代码。
输入“python setup.py build_ext  --inplace”命令,如下图:

什么情况?Python运行速度居然追上了C语言!

命令说明:
build_ext是指明python生成C/C++的扩展模块(build C/C++ extensions (compile/link to build directory))
--inplace指示 将编译后的扩展模块直接放在与hello.py同级的目录中。

从上图看出来,我们在编译过程中出现了错误,那是因为C编译器相关的配置没有设置好,在Windows上一般采用Microsoft VisualStudio,不同的VS版本设置不同。以下是配置说明:
Visual Studio 2010 (VS10): SET VS90COMNTOOLS=%VS100COMNTOOLS%
Visual Studio 2012 (VS11): SET VS90COMNTOOLS=%VS110COMNTOOLS%
Visual Studio 2013 (VS12): SET VS90COMNTOOLS=%VS120COMNTOOLS%
Visual Studio 2015 (VS14): SET VS90COMNTOOLS=%VS140COMNTOOLS%
Visual Studio 2017 (VS14): SET VS90COMNTOOLS=%VS150COMNTOOLS% 
小编电脑里的是VS2010作为C的编译器。
于是输入“SET VS90COMNTOOLS=%VS100COMNTOOLS%”,然后在编译就可以成功了,如下图:

什么情况?Python运行速度居然追上了C语言!

同时在E:/cythontest/ 目录中,生成了几个文件,如下图:

什么情况?Python运行速度居然追上了C语言!

说明:
hello.c是hello.py转化后的C代码文件,可以看到hello.c非常大
hello.pyd是python的动态链接库,我们在使用import hello时会加载
build目录编译过程中生成的临时文件

接下来,我们来调用一下刚刚生成的模块,如下图所示:

什么情况?Python运行速度居然追上了C语言!

到这里说明我们前面所讲的一堆都是可行的,但是接下来问题来了,通过这个方法到底能不能提高效率呢?
于是,我们做了一个测试…

Cython测试

我们写了如下两段测试代码:
test_org.py用来直接运行

import math
import time

time1 = time.time()
for i in range(100000000):
    x = math.sqrt(i)
time2 = time.time()
print time2 - time1

运行结果如下:

什么情况?Python运行速度居然追上了C语言!

test.py用来通过cython生成C语言模块再运行

import math
import time

def f():
    time1 = time.time()
    for i in range(100000000):
        x = math.sqrt(i)
    time2 = time.time()
    print time2 - time1

运行结果如下:

什么情况?Python运行速度居然追上了C语言!

同样的代码,前者耗时26.8240001202,后者则只耗时10.9499998093,从结果对比起来,两者差距还是蛮大的。

写在最后

最后我们来总结一下整个Cython工作的流程,流程图如下:

什么情况?Python运行速度居然追上了C语言!

主要分两步:
1).py文件使用Cython被编译为.c文件;
2).c文件使用C编译器生成.pyd。
生成的.pyd文件可以直接被我们在python中当做模块来调用。

好了,Cython讲完了,您对Cython有哪些更好的看法和使用心得,欢迎扫描下方二维码关注公众号给我们留言交流噢!同时我们为愿意学习Python的同学准备了学习礼包,公众号中回复“Python学习”即可获取。

什么情况?Python运行速度居然追上了C语言!