I want to speed up my code by using memoryviews. here are two classes I use:
cdef class child:
cdef public int[:] move
def __init__(self, move):
self.move = move
cdef class parent:
cdef public:
list children
int[:, :] moves
def __init__(self):
self.children = []
def add_children(self, moves):
cdef int i = 0
cdef int N = len(moves)
for i in range(N):
self.children.append(child(moves[i]))
And this is the code I want to check whether the classes work or not:
temp = []
for i in range(100):
temp.append([i, i+1])
cdef int[:, :] moves = np.asarray(temp, dtype=np.int32)
a = parent()
a.add_children(moves)
for move in moves:
for ch in a.children:
if move == ch.move:
print('ok')
I expect for 100 to print ok
but I get nothing. I know if I use the list(move) == list(ch.move)
I can get the expected output but I don't want the conversion overhead in loops.
Can anyone help me with an efficient way? If anyone has any other suggestion which improves the code speed, It would be appreciated.
I'd probably use numpy.array_equal
. (It accepts memoryviews as well as numpy arrays.)
if numpy.array_equal(move, ch.move):
print("OK")
The main advantage over memcmp
(that the other answer suggests) is that memcmp
will not work on non-contiguous array (which the other answer admits). It's easy to get a non-contiguous memoryview just by taking a column of a 2D memoryview.
You could utilize memcmp
(function that compares memory) from the c library:
from libc.string cimport memcmp
cdef int[:, :] moves = np.asarray(temp, dtype=np.int32)
cdef int[:] move
cdef child ch
a = parent()
a.add_children(moves)
for move in moves:
for ch in a.children:
if memcmp(&move[0], &ch.move[0], move.nbytes) == 0:
print('ok')
However that could (probably) lead to problems if the memoryviews have different dtypes, endianness or strides - because memcmp
just compares the plain memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With