Как указано @DavidW, вы на самом деле не сравниваете идентичные алгоритмы. Ниже я написал две отдельные функции для каждого cython и numba, которые делают то же самое. Первый работает на массив, второй просто дано целое число:
Cython:
cpdef long cy_sum(long[:] A):
cdef long i, n = A.shape[0], s = 0
for i in range(n):
s += A[i]
return s
cpdef long cy_sum2(long i):
cdef long s, x
s = 0
for x in range(i):
s += x
return s
Numba:
@nb.jit(nopython=True)
def nb_sum(A):
s=0
n = A.shape[0]
for i in range(n):
s += A[i]
return s
@nb.jit(nopython=True)
def nb_sum2(i):
s=0
for x in range(i):
s+=x
return s
тестирование, чтобы убедиться, что они дают одинаковые результаты:
N = int(1e6)
d = np.arange(N, dtype=np.int64)
print np.allclose(nb_sum(d), cy_sum(d)) # True
print np.allclose(nb_sum2(N), cy_sum2(N)) # True
И тайминги на моем оборудовании:
%timeit cy_sum(d)
%timeit nb_sum(d)
1000 loops, best of 3: 416 µs per loop
1000 loops, best of 3: 237 µs per loop
%timeit cy_sum2(N)
%timeit nb_sum2(N)
10000000 loops, best of 3: 63.5 ns per loop
10000000 loops, best of 3: 187 ns per loop
Я бы не сделал слишком много выводов из такого микро-теста, но, по крайней мере, сейчас сравниваются эквивалентные реализации.
Потому что вы запустили numba один на одно значение, а остальные на массив. – DavidW
'% timeit sumr (int (1e6))' (строка 7) – DavidW
@DavidW: 'sumr' имеет внутри него цикл, который использует' range'. – BrenBarn