2011-09-16 3 views
3

cython으로 파이썬 코드를 빠르게하려고하는데, cython의 -a 옵션을 사용하여 어디에서 개선 할 수 있는지 알아 보려고합니다. 제 이해는 생성 된 html 파일에서 강조 표시된 행은 파이썬 함수가 호출 된 행입니다 - 정확합니까?Cython numpy 배열 인덱싱

다음과 같은 간단한 함수에서 버퍼 구문을 사용하여 numpy 배열 인수 arr을 선언했습니다. 필자는 파이썬 함수를 호출 할 필요없이 순전히 C로 인덱싱 작업을 수행 할 수 있다고 생각했습니다. 그러나 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'을 사용하는 것이 안전합니까? 실제로 성능에 영향을 미칩니 까?

delnan의 의견 뒤에 편집 : 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); 
    } 
+0

는'편곡인가를 [내가] + = 1 '강조? 또한,'cython -a'에 의해 생성 된 HTML 문서에서 특정 라인에 대해 생성 된 코드를 볼 수 있다고 생각합니다. 아마도 파이썬 API 호출이 해당 라인에서 발생하는 것을 확인하는 데 도움이 될 것입니다. – delnan

답변

4

대답은 하이 라이터가 독자를 바보이다. 코드를 컴파일했고 하이라이트 아래에 생성 된 지침은 오류 케이스와 반환 값을 처리하는 데 필요한 이며 배열 할당과 관련이 없습니다.

실제로 당신이 읽을 수있는 코드를 변경하는 경우 :

def foo(numpy.ndarray[double, ndim=1] arr not None): 
    cdef int i 
    cdef double elem 
    for i in xrange(10): 
     elem = arr[i] 
     arr[i] = 1.0 + elem 
    return # + add this 

하이라이트는 마지막 줄에 및 할당에없는 많은 것이다.

당신은 더 @의 cython.boundscheck 사용하여 코드 속도를 높일 수 있습니다 :

import numpy 
cimport numpy 
cimport cython 

@cython.boundscheck(False) 
def foo(numpy.ndarray[double, ndim=1] arr not None): 
    cdef int i 
    cdef double elem 
    for i in xrange(10): 
     elem = arr[i] 
     arr[i] = 1.0 + elem 
    return 
+0

제공된 C 코드는 바운드 검사를 표시하지 않고 랩 어라운드 색인 계산을 표시합니다. 그래서 나는 질문자가 그의 setup.py에서 그들을 비활성화했다고 가정합니다. – rocksportrocker