在循环中检查两个内存视图的有效方法是什么?

时间:2017-08-05 08:25:11

标签: python python-3.x loops cython typed-memory-views

我想通过使用内存视图来加速我的代码。这是我使用的两个类:

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]))

这是我要检查类是否有效的代码:

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')

我希望100打印ok,但我一无所获。我知道如果我使用list(move) == list(ch.move)我可以获得预期的输出,但我不希望循环中的转换开销。

任何人都可以用有效的方式帮助我吗?如果有人有任何其他建议可以提高代码速度,那将不胜感激。

2 个答案:

答案 0 :(得分:3)

我可能会使用numpy.array_equal。 (它接受内存视图以及numpy数组。)

if numpy.array_equal(move, ch.move):
  print("OK")

memcmp的主要优势(另一个答案表明)是memcmp不适用于非连续数组(另一个答案承认)。通过获取2D内存视图的列,很容易获得非连续的内存视图。

答案 1 :(得分:1)

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.