[Numpy-discussion] Speed up function on cross product of two sets?

Tim Hochberg tim.hochberg at cox.net
Mon Apr 3 10:36:05 CDT 2006


Zachary Pincus wrote:

>> If I were going to make a list it would look something like:
>>
>> 0. Think about your algorithm.
>> 1. Vectorize your inner loop.
>> 2. Eliminate temporaries
>> 3. Ask for help
>> 4. Recode in C.
>> 5 Accept that your code will never be fast.
>>
>> Step zero should probably be repeated after every other step ;)
>
>
> Thanks for this list -- it's a good one.
>
> Since we're discussing this, could I ask about the best way to  
> eliminate temporaries? If you're using ufuncs, is there some way to  
> make them work in-place? Or is the lowest-hanging fruit (temporary- 
> wise) typically elsewhere?

The least cryptic is to use *=, +=, where you can. But that only get's 
you so far.

As you guessed, there is a secret extra argument to ufuncs that allow 
you to do results in place. One could replace scratch=a*(b+sqrt(a)) with:

 >>> scratch = zeros([5], dtype=float)
 >>> a = arange(5, dtype=float)
 >>> b = arange(5, dtype=float)
 >>> sqrt(a, scratch)
array([ 0.        ,  1.        ,  1.41421356,  1.73205081,  2.        ])
 >>> add(scratch, b, scratch)
array([ 0.        ,  2.        ,  3.41421356,  4.73205081,  6.        ])
 >>> multiply(a, scratch)
array([  0.        ,   2.        ,   6.82842712,  14.19615242,  
24.        ])

The downside of this is that your code goes from comprehensible to 
insanely cryprtic pretty fast. I only resort to this in extreme 
circumstances. You could also use numexpr, which should be faster and is 
much less cryptic, but may not be completely stable yet.

Oh, and don't forget step 0, that's sometimes a good way to reduce 
temporaries.

regards,

-tim








More information about the Numpy-discussion mailing list