<h3>解决方法</h3>
<p>如果您使用显式的就地操作,加上<code>out</code>参数,而不是扩充赋值:replace,这将有助于Numba</p>
<pre><code>arr -= arr[3]
</code></pre>
<p>与</p>
^{pr2}$
<p>这使得jitted版本(虽然使用@jit,而不是@njit)的性能与NumPy版本相同。值得注意的是,尝试@njit这个函数现在将失败,告诉您njit无法处理<code>out</code>参数。在</p>
<p>我看到您已经<a href="https://github.com/numba/numba/issues/2644" rel="nofollow noreferrer">opened an issue on this</a>,所以有一个机会,对扩充赋值的处理将被更改为匹配NumPy。在</p>
<h3>为什么会发生这种情况</h3>
<p>正如hpaulj所说,Numba输出相当于在数组的行上循环。Python抖动不能处理NumPy底层的C代码;它需要Python来处理。支持NumPy方法的原因(在某种程度上)是因为Numba开发人员费尽心思将NumPy数组操作解码为标量对象上的显式Python迭代,然后将迭代传递给LLVM。从<a href="http://numba.pydata.org/numba-doc/dev/developer/rewrites.html#the-lower-array-expr-function" rel="nofollow noreferrer">documentation</a>:</p>
<blockquote>
<ul>
<li>Synthesize a Python function that implements the array expression: This new Python function essentially behaves like a Numpy ufunc, returning the result of the expression on scalar values in the broadcasted array arguments. The lowering function accomplishes this by translating from the array expression tree into a Python AST.</li>
<li>Compile the synthetic Python function into a kernel: At this point, the lowering function relies on existing code for lowering ufunc and DUFunc kernels, calling <code>numba.targets.numpyimpl.numpy_ufunc_kernel()</code> after defining how to lower calls to the synthetic function.</li>
</ul>
<p>The end result is similar to loop lifting in Numba’s object mode.</p>
</blockquote>
<p>前面提到的<a href="https://github.com/numba/numba/blob/master/numba/targets/npyimpl.py#L296" rel="nofollow noreferrer">^{<cd3>}</a>收集索引并在索引上迭代</em>。如果被迭代的对象在迭代过程中发生了变化,这会使事情变得棘手。在</p>