Cython обновление атрибутов объекта - PullRequest
0 голосов
/ 14 апреля 2020

Я экспериментирую с объектом Cython, где я хотел бы иметь возможность многократно обновлять его атрибуты в соответствии с некоторыми условиями. Фиктивный код ниже просто меняет атрибуты произвольно, чтобы продемонстрировать проблему, с которой я сталкиваюсь. Я запускаю этот пример в блокноте Jupyter.

%load_ext Cython
%%cython -a

cdef class A_cy:  
    cdef int[:] a, b

    def __cinit__(self, a, b):
        self.a = a
        self.b = b

cpdef void swap_attributes_cy(int[:] x):
    cdef:
        Py_ssize_t i
        A_cy container = A_cy(x, x)
        int _a

    for i in range(1000000): 
        _a = container.a

        container.a = container.b
        container.b = _a

При тестировании этого варианта на чистой версии python, т.е.

class A_py:  
    def __init__(self, a, b):
        self.a = a
        self.b = b

def swap_attributes_py(x):
    container = A_py(x,x)

    for i in range(1000000):
        _a = container.a

        container.a = container.b
        container.b = _a

Эта версия Cython медленнее (на моей машине), чем python (~200ms против ~150ms). Однако , если я изменю тип атрибутов на int, версия python останется неизменной, но версия Cython займет ~110ns! Я изо всех сил пытаюсь понять, почему есть разница при попытке поменять memoryview против int? Нужно ли использовать malloc, realloc и free для обмена представлениями памяти?

Редактировать

Если я использую cdef np.ndarray a, b вместо cdef int[:] a, b, версия Cython теперь принимает ~6.7ms. Можно ли все же улучшить это?

...