3D 배열에 대한 NumPy 중첩 루프가 Cython과 비교할 때 너무 느리다는 것이 혼란 스럽습니다. 나는 간단한 예를 썼다.NumPy 대 Cython - 너무 느린 중첩 루프?
파이썬/NumPy와 버전 :
import numpy as np
def my_func(a,b,c):
s=0
for z in xrange(401):
for y in xrange(401):
for x in xrange(401):
if a[z,y,x] == 0 and b[x,y,z] >= 0:
c[z,y,x] = 1
b[z,y,x] = z*y*x
s+=1
return s
a = np.zeros((401,401,401), dtype=np.float32)
b = np.zeros((401,401,401), dtype=np.uint32)
c = np.zeros((401,401,401), dtype=np.uint8)
s = my_func(a,b,c)
Cythonized 버전 : 약 my_func()
실행의
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def my_func(np.float32_t[:,:,::1] a, np.uint32_t[:,:,::1] b, np.uint8_t[:,:,::1] c):
cdef np.uint16_t z,y,x
cdef np.uint32_t s = 0
for z in range(401):
for y in range(401):
for x in range(401):
if a[z,y,x] == 0 and b[x,y,z] >= 0:
c[z,y,x] = 1
b[z,y,x] = z*y*x
s = s+1
return s
Cythonized 버전. 6500 배 빠릅니다. if 문과 배열 액세스만으로도 더 간단한 함수는 10000 배 더 빠릅니다. my_func()
의 Python 버전은 500.651 초 걸립니다. 끝내기 위해. 상대적으로 작은 3D 배열을 너무 느리게 반복하거나 코드에서 실수를 저 지르지 않았습니까?
Cython 버전 0.21.1, Python 2.7.5, GCC 4.8.1, Xubuntu 13.10.
타이밍에 대해 실제로 언급 할 수는 없습니다.그러나 나는 파이썬이 아닌 "작은"6500 만회 반복으로 루프를 호출하지 않을 것입니다. 이것이 numpy가 존재하는 이유입니다. 모든 배열 요소에 대해 파이썬 루프를 작성하는 대신 numpy가 내부적으로 요소를 반복하도록해야합니다. – sebastian
'@cython.boundscheck (False)'는 python for 루프에서 수행되는 최대 15 억 개의 경계 검사를 제거합니다. 그것은 401^3 반복입니다 * 4 배열 액세스 * 액세스 당 3 인덱스 * 인덱스 당 2 검사. 음수 색인 생성을 허용하지 않았으므로이 숫자에 2를 곱하면됩니다. – Dunes
이것은 정확하게 Numba가 코딩을하지 않아도 당신에게 아주 빠른 스피드 업을 제공 할 Python 종류입니다. 그냥'''numb.jit'''로 함수를 꾸미십시오. –