Я начал использовать memoryviews в cython для доступа к массивам numpy. Одно из их различных преимуществ заключается в том, что они значительно быстрее, чем поддержка старого буфера numpy: http://docs.cython.org/src/userguide/memoryviews.html#comparison-to-the-old-buffer-support
Однако у меня есть пример, в котором поддержка старого буфера numpy работает быстрее, чем memoryviews! Как это может быть?! Интересно, правильно ли я использую memoryviews?
Это мой тест:
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef np.ndarray[np.uint8_t, ndim=2] image_box1(np.ndarray[np.uint8_t, ndim=2] im,
np.ndarray[np.float64_t, ndim=1] pd,
int box_half_size):
cdef unsigned int p0 = <int>(pd[0] + 0.5)
cdef unsigned int p1 = <int>(pd[1] + 0.5)
cdef unsigned int top = p1 - box_half_size
cdef unsigned int left = p0 - box_half_size
cdef unsigned int bottom = p1 + box_half_size
cdef unsigned int right = p0 + box_half_size
cdef np.ndarray[np.uint8_t, ndim=2] box = im[top:bottom, left:right]
return box
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef np.uint8_t[:, ::1] image_box2(np.uint8_t[:, ::1] im,
np.float64_t[:] pd,
int box_half_size):
cdef unsigned int p0 = <int>(pd[0] + 0.5)
cdef unsigned int p1 = <int>(pd[1] + 0.5)
cdef unsigned int top = p1 - box_half_size
cdef unsigned int left = p0 - box_half_size
cdef unsigned int bottom = p1 + box_half_size
cdef unsigned int right = p0 + box_half_size
cdef np.uint8_t[:, ::1] box = im[top:bottom, left:right]
return box
Результаты по срокам:
image_box1: набранное число: 100000 циклов, лучшее из 3: 11,2 мкс за цикл
image_box2: memoryview: 100000 циклов, лучшее из 3: 18,1 мкс на цикл
Эти измерения выполняются из IPython с использованием% timeit image_box1 (im, pd, box_half_size)
np.ndarray
также во второй функции (я полагаю), что уже может объяснить замедление, поскольку созданиеnp.ndarray
- это небольшая дополнительная работа, а в целом здесь сделано не так много. - person seberg   schedule 09.10.2012