我用以下代码测试了你的问题:
#cython: wraparound=False
#cython: boundscheck=False
#cython: cdivision=True
#cython: nonecheck=False
#cython: profile=False
def loop(int k):
return real_loop(k)
def loop2(int k):
cdef float a
real_loop2(k, &a)
return a
def loop3(int k):
real_loop3(k)
return None
def loop4(int k):
return real_loop4(k)
def loop5(int k):
cdef float a
real_loop5(k, &a)
return a
cdef float real_loop(int k):
cdef int i
cdef float a
a = 0.
for i in range(k):
a += a**2 / (a + 1)
return a
cdef void real_loop2(int k, float *a):
cdef int i
a[0] = 0.
for i in range(k):
a[0] += a[0]**2 / (a[0] + 1)
cdef void real_loop3(int k):
cdef int i
cdef float a
a = 0.
for i in range(k):
a += a**2 / (a + 1)
cdef float real_loop4(int k):
cdef int i
cdef float a
a = 0.
for i in range(k):
a += a*a / (a + 1)
return a
cdef void real_loop5(int k, float *a):
cdef int i
a[0] = 0.
for i in range(k):
a[0] += a[0]*a[0] / (a[0] + 1)
wherereal_loop()
接近你的函数,修改后的公式,a
因为原来的公式看起来很奇怪。
函数real_loop2()
不返回任何值,只是a
通过引用更新。
函数real_loop3()
没有返回任何值。
检查生成的C
代码real_loop3()
可以看到循环在那里,并且代码被调用......但我和@dmytro有相同的结论,改变k
不会显着改变时间......所以必须有一点我在这里失踪了。
从下面的时间我们可以说这return
不是瓶颈,因为real_loop2()
和real_loop5()
have 不返回任何值,它们的性能分别与real_loop()
和相同。real_loop4()
In [2]: timeit _stack.loop(100000)
1000 loops, best of 3: 1.71 ms per loop
In [3]: timeit _stack.loop2(100000)
1000 loops, best of 3: 1.69 ms per loop
In [4]: timeit _stack.loop3(100000)
10000000 loops, best of 3: 78.5 ns per loop
In [5]: timeit _stack.loop4(100000)
1000 loops, best of 3: 913 µs per loop
In [6]: timeit _stack.loop5(100000)
1000 loops, best of 3: 979 µs per loop
请注意 ~2X 的加速更改a**2
为a*a
,因为需要在循环内a**2
调用函数。powf()