<p>首先,您需要多次调用函数(>;1000),并取每个函数所用时间的平均值,以准确了解它们之间的差异。一次调用每个函数将不够精确。</p>
<p>其次,在函数中花费的时间将受到其他因素的影响,而不仅仅是带有除法的循环。调用这样的<code>def</code>即Python函数需要一些传递和返回参数的开销。此外,在函数中创建<em>numpy</em>数组需要时间,因此两个函数中的循环中的任何差异都不会太明显。</p>
<p>最后,请参见这里(<a href="https://github.com/cython/cython/wiki/enhancements-compilerdirectives">https://github.com/cython/cython/wiki/enhancements-compilerdirectives</a>),将c-division指令设置为<em>False</em>将导致大约35%的速度损失。我认为这还不足以显示在你的例子中,考虑到其他间接费用。我检查了Cython输出的<strong>C</strong>代码,<em>示例2</em>的代码明显不同,并且包含额外的零除检查,但是当我分析它时,运行时的差异可以忽略不计。</p>
<p>为了说明这一点,我运行了下面的代码,在这里我将您的代码并将<code>def</code>函数变成<code>cdef</code>函数,即<strong>Cython</strong>函数,而不是<strong>Python</strong>函数。这大大减少了传递和返回参数的开销。我还修改了<em>example1</em>和<em>example2</em>来计算numpy数组中的值的和,而不是创建一个新数组并填充它。这意味着几乎所有在每个函数中花费的时间现在都在循环中,所以应该更容易看到任何差异。我也运行了很多次每个函数,使D更大。</p>
<pre><code>@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
@cython.cdivision(True)
@cython.profile(True)
cdef double example1(double[:] xi, double[:] a, double[:] b, int D):
cdef int k
cdef double theSum = 0.0
for k in range(D):
theSum += (xi[k] - a[k]) / (b[k] - a[k])
return theSum
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
@cython.profile(True)
@cython.cdivision(False)
cdef double example2(double[:] xi, double[:] a, double[:] b, int D):
cdef int k
cdef double theSum = 0.0
for k in range(D):
theSum += (xi[k] - a[k]) / (b[k] - a[k])
return theSum
def testExamples():
D = 100000
x = np.random.rand(D)
a = np.zeros(D)
b = np.random.rand(D) + 1
for i in xrange(10000):
example1(x, a, b, D)
example2(x, a, b,D)
</code></pre>
<p>我通过profiler(<em>python-m cProfile-s cumulative</em>)运行了这段代码,相关输出如下:</p>
<pre><code>ncalls tottime percall cumtime percall filename:lineno(function)
10000 1.546 0.000 1.546 0.000 test.pyx:26(example2)
10000 0.002 0.000 0.002 0.000 test.pyx:11(example1)
</code></pre>
<p>这表明示例2要慢得多。如果我在示例2中打开c除法,那么对于示例1和示例2,花费的时间是相同的,所以这显然有一个显著的效果。</p>