前言
Cython关键字def、cdef、cpdef语法层面的含义,我不再多说,若毫无概念的请移步至本篇《第1篇:Cython的数据类型》,本篇只要是通过Cython不同的关键字修饰同一个算法,在不同情况下,性能的差异。
py文件封装的def函数
Python版本实现质数筛算法,测试数量级100,000,000,封装在primer.py文件中
def sieveOfEratosthenes(n):
pr = [True for i in range(n + 1)]
p = 2
res=list()
while (p * p <= n):
if (pr[p] == True):
for i in range(p * p, n + 1, p):
pr[i] = False
#end-for
#end-if
p += 1
#end-while
for p in range(2,n):
if pr[p]:
res.append(p)
#end-if
#end-for
return res
#end-def
app.py文件内的测试代码
if __name__=='__main__':
from primer import sieveOfEratosthenes
import timeit
ts=[]
for i in range(1,4):
print("cacluation,",i,"times")
start=timeit.default_timer()
res=sieveOfEratosthenes(100000000)
end=timeit.default_timer()
ts.append(end-start)
#end-for
print("一共{}个质数".format(len(res)))
sum_t=0.0
avg_t=sum(ts)/len(ts)
print("耗时:{}s".format(avg_t))
运行三次后的平均耗时19.61s
![](https://img.haomeiwen.com/i16148197/6912b40d4d1c4593.png)
pyx文件封装的Python函数
就是上面py文件封装的Python函数,我们用pyx文件封装该函数,此时我们使用
cythonize -i -a ./primer.pyx
![](https://img.haomeiwen.com/i16148197/f4d0f69885dd6f37.png)
同理,执行上一个示例的app.py,得出运行时间15.58秒,相比封装在py文件中的性能提升25.86%
![](https://img.haomeiwen.com/i16148197/a4a487261197ea07.png)
这次,我们对pyx文件中的Python函数的位置参数,局部变量的数据类型静态化,指定对应Cython的支持的数据类型
![](https://img.haomeiwen.com/i16148197/0ee0fa9734379176.png)
再次执行cythonize -i -a ./primer.pyx,然后运行./app.py,此次运行耗时10.66s,为求严谨我这次多测试了12次,相比前一种情况封装在pyx文件的Python函数的性能提升了46.15%
![](https://img.haomeiwen.com/i16148197/125e057d619e94ee.png)
pyx文件封装的Cython函数
我们将上面的示例再做些特殊处理,如下图所示有def关键字定义的函数我们叫做Python函数,它是对Python虚拟机可见的,然而cdef关键字定义的函数会被Cython编译器编译为C/C++的模块,它会被封装到一个共享对象(*.so文件)可执行扩展模块当中(这个过程我们又叫装箱,boxing),因此对于Python虚拟机,这些函数是不可见的,因此Python虚拟机需要传递参数并调用这些C/C++函数,需要在pyx文件中再定义一个由关键字def定义的Python函数,然后由该Python函数调用C/C++模块(箱中)的函数。
![](https://img.haomeiwen.com/i16148197/228ac0badfb52f38.png)
同理,编译后,此次测行我们运行了10次,平均耗时10.73s跟上一次运行的时间差别不大。
![](https://img.haomeiwen.com/i16148197/5a299d1fff7eb79a.png)
pyx文件的cpdef函数
这次我们用cpdef关键字来修饰函数,如下图所示的
![](https://img.haomeiwen.com/i16148197/21415d589e17b295.png)
运行耗时,最好的一是平均11.47秒
![](https://img.haomeiwen.com/i16148197/a70f56f3f34571e3.png)
性能对比
从上面的各种情况,我们对Python程序中运算量较大的代码段进行向降级至C/C++代码,Cython的cdef关键字将函数局部变量和参数的数据类型静态化确实是会令Python的程序加快。
![](https://img.haomeiwen.com/i16148197/cec594a44a3b4ec2.png)
网友评论