Я пытаюсь ускорить некоторый код Python с помощью Cython, и я использую опцию -a
в Cython, чтобы посмотреть, где я могу что-то улучшить.Насколько я понимаю, в сгенерированном html-файле выделенные строки - это те, где вызываются функции python - это правильно?
В следующей тривиальной функции я объявил аргумент numpy array arr
, используя буферсинтаксис.Я подумал, что это позволяет выполнять операции индексации исключительно в C без необходимости вызова функций Python.Однако cython -a
(версия 0.15) выделяет строку, где я установил значение элемента arr
, но не ту, где я читал один из его элементов.Почему это происходит?Есть ли более эффективный способ доступа к элементам массива numpy?
import numpy
cimport numpy
def foo(numpy.ndarray[double, ndim=1] arr not None):
cdef int i
cdef double elem
for i in xrange(10):
elem = arr[i] #not highlighted
arr[i] = 1.0 + elem #highlighted
РЕДАКТИРОВАТЬ: Кроме того, как буферный аргумент mode
взаимодействует с numpy?Предполагая, что я не изменил order
аргумент numpy.array
по умолчанию, всегда ли безопасно использовать mode='c'
?Это на самом деле влияет на производительность?
РЕДАКТИРОВАТЬ после комментария Делнана: arr[i] += 1
также выделяется (вот почему я разделил его в первую очередь, чтобы увидеть, какая часть операции вызывала проблему).Если я отключаю проверку границ для упрощения (это не имеет значения для того, что подсвечивается), сгенерированный код c:
/* "ct.pyx":11
* cdef int i
* cdef double elem
* for i in xrange(10): # <<<<<<<<<<<<<<
* elem = arr[i]
* arr[i] = 1.0 + elem
*/
for (__pyx_t_1 = 0; __pyx_t_1 < 10; __pyx_t_1+=1) {
__pyx_v_i = __pyx_t_1;
/* "ct.pyx":12
* cdef double elem
* for i in xrange(10):
* elem = arr[i] # <<<<<<<<<<<<<<
* arr[i] = 1.0 + elem
*/
__pyx_t_2 = __pyx_v_i;
__pyx_v_elem = (*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_2, __pyx_bstride_0_arr));
/* "ct.pyx":13
* for i in xrange(10):
* elem = arr[i]
* arr[i] = 1.0 + elem # <<<<<<<<<<<<<<
*/
__pyx_t_3 = __pyx_v_i;
*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_3, __pyx_bstride_0_arr) = (1.0 + __pyx_v_elem);
}