由于性能问题,我开始学习Cython。这段代码是尝试在运输建模(用于规划)领域中实现一些新算法的。
我决定从一个非常简单的函数开始,这个函数我会使用很多次(数亿次),并且绝对可以从性能提升中受益。
我用三种不同的方式实现了这个函数,并对它们进行了相同参数的测试(为了简单起见),每种方法都测试了1000万次:
Cython模块中的Cython代码。 运行时间:3.35秒
Cython模块中的Python代码。 运行时间:4.88秒
主脚本中的Python代码。 运行时间:2.98秒
如您所见,Cython代码比Cython模块中的Python代码慢了45%,比主脚本中编写的代码慢了64%。这怎么可能? 我哪里犯了错?
以下是Cython代码:
def BPR2(vol, cap, al, be):
con=al*pow(vol/cap,be)
return con
def func (float volume, float capacity,float alfa,float beta):
cdef float congest
congest=alfa*pow(volume/capacity,beta)
return congest
测试的脚本如下:
agora=clock()
for i in range(10000000):
q=linkdelay.BPR2(10,5,0.15,4)
agora=clock()-agora
print agora
agora=clock()
for i in range(10000000):
q=linkdelay.func(10,5,0.15,4)
agora=clock()-agora
print agora
agora=clock()
for i in range(10000000):
q=0.15*pow(10/5,4)
agora=clock()-agora
print agora
我知道像是超越函数(幂)会比较慢的问题,但我不认为这应该是一个问题。
因为查找函数空间中的函数需要一定的开销,如果我传递一个数组给函数并返回一个数组,这样会提高性能吗?我能够使用Cython编写的函数来返回一个数组吗?
参考资料:
- Windows 7 64位
- Python 2.7.3 64位
- Cython 0.16 64位
- Windows Visual Studio 2008
PyObject*
转换为float再进行反向转换,是不是有点过于繁琐了呢?对于如此小的函数来说,似乎开销有些大。 - Voofloat
类型数据,而是需要使用double
类型数据吗? - K. Brafford