numpy.cross and similiar functions: Do they allocate a new array on every call?
<p>When I use <code>numpy.cross</code>, it will <em>return</em> an array with the results. There's no way to compute <em>into</em> an existing array. The same holds for other functions.</p>

<ol>
<li>Isn't it extremely inefficient to allocate a new array upon each call?</li>
<li>If so, is there a way to speed it up?</li>
</ol>

<p>The current version of <code>np.cross</code> (as of 1.9) takes great effort to avoid temporary arrays.  Where possible is uses views of the inputs, even when it has to roll the axes.  It creates the output array</p>

<pre><code>cp = empty(shape, dtype)
</code></pre>

<p>and then takes care to perform calculation in-place, using the <code>out</code> of <code>multiply</code> and <code>-=</code> kinds of assignment.</p>

<pre><code>multiply(a0, b1, out=cp)
cp -= a1 * b0
</code></pre>

<p>However most of these operations are still buffered.  That is <code>a1*b0</code> writes to a temporary buffer array, which is then subtracted from <code>cp</code>.  </p>

<p>Usually we don't worry about those temporary arrays.  We let the developers worry about efficiency and reliability.  Handling temporary buffers is compiled code's responsibility, not ours.</p>

<p>The unbuffered <code>add.at</code> documentation gives some insight into the use of buffering or not.  This unbuffered <code>.at</code> method is used to certain serial operations that the regular buffered versions can't handle.  But it is not meant as a way of speeding up code.</p>

<p>It sounds like you want <code>np.cross</code> to take an <code>out</code> parameter, thinking that if you can use</p>

<pre><code>cp = np.empty(rightsize)
for a,b in zip(A,B):
   np.cross(A,B,out=cp)
   &lt;use cp&gt;
</code></pre>

<p>it will be a lot faster than </p>

<pre><code>for a,b, in zip(A,B):
   cp = np.cross(A,B)
   &lt;use cp&gt;
</code></pre>

<p>I doubt if that would help.  In the big picture the <code>cp=np.empty(...)</code> is a minor time consumer.  </p>

<p>But lets do a time test with <code>np.multiply</code> which does take an <code>out</code>:</p>

<pre><code>In [18]: x = np.ones((1000,1000))
In [19]: %%timeit 
    ...: y = np.multiply(x,x)
    ...: 
100 loops, best of 3: 12.4 ms per loop
In [20]: %%timeit y = np.empty(x.shape) 
    ...: np.multiply(x,x, out=y)
    ...: 
100 loops, best of 3: 6.48 ms per loop
</code></pre>

<p>OK, taking the allocation out of the timing loop does cut the time in half.</p>

<p>But if you are repeatedly calling <code>np.cross</code> (or some other function like it), I think you should worry more about the number of repeats than details like array reuse.</p>

<pre><code>np.cross(np.ones((N,3)), np.ones((N,3)))
</code></pre>

<p>is considerably faster than</p>

<pre><code>for i in range(N):
    np.cross(np.ones(3), np.ones(3))
</code></pre>

<p>But it would be easy to make a copy of <code>np.cross</code> (it's pure Python), and modify it to take an <code>out</code>.  Try it and see if it makes a difference.  As long as you use a correct sized <code>cp</code> it should work. You'd have to decide whether to bypass the <code>shape</code> and <code>dtype</code> checks that preceed the <code>cp=empty...</code> line.</p>

python numpy