2

I'm using this to cleanup array in Cython

cdef void fill(DTYPE[:] ary):
    cdef int i, size = len(ary)
    for i in range(size): ary[i] = 0

is there a faster way ?


they seems to have it,cdef'd

source

cdef inline void zero(array self):
    """ set all elements of array to zero. """
    memset(self.data.as_chars, 0, Py_SIZE(self) * self.ob_descr.itemsize)

generated code :

    cdef array.array rows
    array.zero(rows)

__pyx_f_7cpython_5array_zero(__pyx_v_rows);

but if :

    cdef float[::1] rows

@DavidW example generates a cleaner version i.e. for-loop


summarized it here and added some more tricks

sten
  • 7,028
  • 9
  • 41
  • 63
  • 1
    I _think_ `memset` can be used, based on [the docs](https://cython.readthedocs.io/en/latest/src/tutorial/array.html). Firstly import it `from libc.string cimport memset` and then something like `memset(ary, 0, size*sizeof(ary))` or `memset(ary.data.as_voidptr, 0, size*sizeof(ary))`. Not quite sure though – Breno Feb 05 '22 at 20:38
  • 1
    Though, [according to this SO answer](https://stackoverflow.com/a/7367803/13132315), it seems that `memset` yields the same assembly instructions as the `for` loop if the compiler is configured properly. – Breno Feb 05 '22 at 20:54
  • `memset` relies on the array being contiguous, which you don't guarantee here. – DavidW Feb 05 '22 at 22:28

1 Answers1

1
cdef void fill(double[:] ary):
    ary[:] = 0

compiles. It's certainly the clearest way and is converted to a straightforward looking C loop. It also means that you don't have to worry about turning off boundschecking and negative indexing.

It'll be helped a little if you declare ary as contiguous (double[::1] ary), although of course that restricts the types of arrays it can do. If you aren't prepared to only accept contiguous arrays, then you should not use memset since it'll be zeroing stuff outside your array.

DavidW
  • 29,336
  • 6
  • 55
  • 86