Numpy slow at vector cross product?

BartC bc at freeuk.com
Tue Nov 22 14:18:07 EST 2016


On 22/11/2016 16:48, Steve D'Aprano wrote:
> On Tue, 22 Nov 2016 11:45 pm, BartC wrote:
>
>
>> I will have a look. Don't forget however that all someone is trying to
>> do is to multiply two vectors. They're not interested in axes
>> transformation or making them broadcastable, whatever that means.
>
> You don't know that.

When I did vector arithmetic at school, the formula for the 
cross-product of (x1,y1,z1) with (x2,y2,z2) was quite straightforward. 
This is what you expect given a library function to do the job. 
Especially in an implementation that could be crippled by running as 
unoptimised byte-code.

If someone was given the task of cross-multiplying two three-element 
vectors, the formula in the text-book (or Wikipedia) is what they would 
write.

> Could numpy optimize the single pair of vectors case a bit better? Perhaps
> they could. It looks like there's a bunch of minor improvements which could
> be made to the code, a few micro-optimizations that shave a microsecond or
> two off the execution time. And maybe they could even detect the case where
> the arguments are a single pair of vectors, and optimize that. Even
> replacing it with a naive pure-Python cross product would be a big win.

The code it ends up executing for individual pairs of vectors is a joke. 
97% of what it does is nothing to do with the cross-product!

> But for the big array of vectors case, you absolutely have to support doing
> fast vectorized cross-products over a huge number of vectors.

That's how I expected numpy to work. I said something along those lines 
in my first post:

BC:
 > Maybe numpy has extra overheads, and the arrays being operated on are
 > very small, but even so, 30 times slower than CPython? (2.5 to 0.083
 > seconds.)


> py> a = np.array([
> ...     [1, 2, 3],
> ...     [4, 5, 6],
> ...     [7, 8, 9],
> ...     ]*1000
> ...     )
> py> b = np.array([
> ...     [9, 8, 7],
> ...     [6, 5, 4],
> ...     [3, 2, 1],
> ...     ]*1000
> ...     )
> py> a.shape
> (3000, 3)
> py> result = np.cross(a, b)
> py> result.shape
> (3000, 3)
>
> On my computer, numpy took only 10 times longer to cross-multiply 3000 pairs
> of vectors than it took to cross-multiply a single pair of vectors. If I
> did that in pure Python, it would take 3000 times longer, or more, so numpy
> wins here by a factor of 300.

I tested this with 3 million pairs on my machine. It managed 8 million 
products per second (about the same as the simplest Python code, but run 
with pypy), taking nearly 0.4 seconds. Except it took over 4 seconds to 
create the special numpy arrays!

Setting up ordinary arrays was much faster, but then the cross-product 
calculation was slower.

-- 
bartc



More information about the Python-list mailing list