문제

나는 Python에서 CFFI 모듈을 쓰는 것으로 놀고 있었고, 속도가 표준 파이썬을 올바르게 사용하는지 궁금하게 만들고 있습니다.그것은 나를 완전히 전환하고 싶습니다!진실로 훌륭한 파이썬 라이브러리가 있으므로 C에서 자신을 구분 할 수 없었기 때문에 이것은 정말로 가설이 더 이상합니다.

이 예제는 numpy 배열과 함께 사용되는 파이썬의 합계 기능과 C 함수와 비교할 때 얼마나 느리게 작동 하는지를 보여줍니다.숫자 배열의 합계를 계산하는 더 빨리 Pyhonic 방식이 있습니까?

def cast_matrix(matrix, ffi):
    ap = ffi.new("double* [%d]" % (matrix.shape[0]))
    ptr = ffi.cast("double *", matrix.ctypes.data)
    for i in range(matrix.shape[0]):
        ap[i] = ptr + i*matrix.shape[1]                                                                
    return ap 

ffi = FFI()
ffi.cdef("""
double sum(double**, int, int);
""")
C = ffi.verify("""
double sum(double** matrix,int x, int y){
    int i, j; 
    double sum = 0.0;
    for (i=0; i<x; i++){
        for (j=0; j<y; j++){
            sum = sum + matrix[i][j];
        }
    }
    return(sum);
}
""")
m = np.ones(shape=(10,10))
print 'numpy says', m.sum()

m_p = cast_matrix(m, ffi)

sm = C.sum(m_p, m.shape[0], m.shape[1])
print 'cffi says', sm
.

함수 작동을 보여주기 위해

numpy says 100.0
cffi says 100.0
.

이제이 간단한 기능을하면 NUMPY가 정말로 느리게 발견됩니다! 나는 올바른 방법으로 숫자를 사용하고 있습니까?파이썬에서 합계를 계산하는 더 빠른 방법이 있습니까?

import time
n = 1000000

t0 = time.time()
for i in range(n): C.sum(m_p, m.shape[0], m.shape[1])
t1 = time.time()

print 'cffi', t1-t0

t0 = time.time()
for i in range(n): m.sum()
t1 = time.time()

print 'numpy', t1-t0
.

시간 :

cffi 0.818415880203
numpy 5.61657714844
.

도움이 되었습니까?

해결책

numpy는 Python 오버 헤드 (아마도 CFFI와 유사한)와 일반성의 두 가지 이유로 c보다 느리게합니다. NUMPY는 다른 데이터 유형의 무리에서 임의의 차원의 배열을 처리하도록 설계되었습니다. CFFI를 사용한 예제는 2D 플로트 배열을 위해 만들어졌습니다. 비용은 여러 줄의 코드 대 .sum(), 6 자 이상 5 마이크로 초 미만을 저장했습니다. (그러나 물론, 당신은 이미 이것을 알았습니다). 나는 단지 CPU 시간이 저렴한 것보다 훨씬 저렴하다는 것을 강조하고 싶습니다.

이제, 숫자를 숫자로 붙이고 더 나은 성능을 얻으려면 최선의 옵션은 병목 현상 . 그들은 1과 2D 배열에 최적화 된 몇 가지 기능을 제공하며, 빠른 타오르는 것입니다. 귀하의 경우, 0.35에서 실행 시간을 0.35로 또는 CFFI만큼 빨리 두 배로 늘릴 수있는 16 배 빠릅니다.

병목 현상이없는 다른 기능의 경우 Cython을 사용할 수 있습니다. 더 많은 Pythonic 구문으로 C 코드를 작성하는 데 도움이됩니다. 또는 당신이 될 것이라면, 당신이 속도에 만족할 때까지 점진적으로 파이썬을 c로 변환하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top