Returning numpy scalars in cython functions

The cython function below returns a long int: @cython.boundscheck(False) def mysum(np.ndarray[np.int64_t, ndim=1] a): "sum of 1d numpy array with dtype=np.int64." cdef Py_ssize_t i cdef int asize = a.shape[0] cdef np.int64_t asum = 0 for i in range(asize): asum += a[i] return asum What's the best way to make it return a numpy long int, or whatever it is called, that has dtype, ndim, size, etc. class methods? The only thing I could come up with is changing the last line to return np.array(asum)[()] It works. And adds some overhead:
a = np.arange(10) timeit mysum(a) 10000000 loops, best of 3: 167 ns per loop timeit mysum2(a) 1000000 loops, best of 3: 984 ns per loop
And for scale:
timeit np.sum(a) 100000 loops, best of 3: 3.3 us per loop
I'm new to cython. Did I miss any optimizations in the mysum function above?

A Thursday 18 November 2010 18:51:04 Keith Goodman escrigué:
The cython function below returns a long int:
@cython.boundscheck(False) def mysum(np.ndarray[np.int64_t, ndim=1] a): "sum of 1d numpy array with dtype=np.int64." cdef Py_ssize_t i cdef int asize = a.shape[0] cdef np.int64_t asum = 0 for i in range(asize): asum += a[i] return asum
What's the best way to make it return a numpy long int, or whatever it is called, that has dtype, ndim, size, etc. class methods? The only thing I could come up with is changing the last line to
return np.array(asum)[()]
It works. And adds some overhead:
a = np.arange(10) timeit mysum(a)
10000000 loops, best of 3: 167 ns per loop
timeit mysum2(a)
1000000 loops, best of 3: 984 ns per loop
And for scale:
timeit np.sum(a)
100000 loops, best of 3: 3.3 us per loop
Perhaps the scalar constructor is your best bet:
type(np.array(2)[()]) <type 'numpy.int64'> type(np.int_(2)) <type 'numpy.int64'> timeit np.array(2)[()] 1000000 loops, best of 3: 791 ns per loop timeit np.int_(2) 1000000 loops, best of 3: 234 ns per loop
-- Francesc Alted

On Thu, Nov 18, 2010 at 10:08 AM, Francesc Alted <faltet@pytables.org> wrote:
A Thursday 18 November 2010 18:51:04 Keith Goodman escrigué:
What's the best way to make it return a numpy long int, or whatever it is called, that has dtype, ndim, size, etc. class methods? The only thing I could come up with is changing the last line to
return np.array(asum)[()]
Perhaps the scalar constructor is your best bet:
type(np.array(2)[()]) <type 'numpy.int64'> type(np.int_(2)) <type 'numpy.int64'> timeit np.array(2)[()] 1000000 loops, best of 3: 791 ns per loop timeit np.int_(2) 1000000 loops, best of 3: 234 ns per loop
Perfect! Thank you.
a = np.arange(10) timeit mysum2(a) 1000000 loops, best of 3: 1.16 us per loop timeit mysum2_francesc(a) 1000000 loops, best of 3: 451 ns per loop
I also added @cython.wraparound(False).
participants (2)
-
Francesc Alted
-
Keith Goodman