Я играл с Cython в рамках подготовки к другой работе. Я попробовал простой тестовый пример и заметил что-то странное в том, как мой код работает для больших размеров проблем. Я создал простую функцию min/max, которая вычисляет min и max массива 2D float32 и сравнивает его с запуском numpy.min(a), numpy.max(a)
. Для массива из 10000 элементов производительность была одинаковой. Для массива из 1000000 элементов cython выполнялся намного хуже. Вот мой Cython код:Cython vs numpy performance scaling
import numpy
cimport cython
cimport numpy
DTYPE = numpy.float32
ctypedef numpy.float32_t DTYPE_t
@cython.boundscheck(False)
@cython.wraparound(False)
def minmax_float32(numpy.ndarray[DTYPE_t, ndim=2] arr):
cdef DTYPE_t min = arr[0, 0]
cdef DTYPE_t max = arr[0, 0]
cdef int row_max = arr.shape[0]
cdef int col_max = arr.shape[1]
cdef int x, y
for y in range(row_max):
for x in range(col_max):
if arr[y, x] < min:
min = arr[y, x]
if arr[y, x] > max:
max = arr[y, x]
return min, max
А вот мой простой выбор времени сделано в IPython:
a = numpy.random.random(10000).reshape((100, 100)).astype(numpy.float32)
%timeit -r3 -n50 (numpy.min(a), numpy.max(a))
# 50 loops, best of 3: 22.2 µs per loop
%timeit -r3 -n50 minmax_float32(a)
# 50 loops, best of 3: 23.8 µs per loop
a = numpy.random.random(1000000).reshape((1000, 1000)).astype(numpy.float32)
%timeit -r3 -n50 (numpy.min(a), numpy.max(a))
# 50 loops, best of 3: 307 µs per loop
%timeit -r3 -n50 minmax_float32(a)
# 50 loops, best of 3: 1.22 ms per loop
307/22.2
# 13.82882882882883
1220/23.8
# 51.26050420168067
Кто-нибудь есть идеи, почему Cython занимает так много больше времени для увеличения ввода? И это было то, с чем я играл, но если у вас есть какие-то подсказки или уловки, мне интересно их услышать. Заранее спасибо.
Редактирование: Я провел эти тесты на macbook 10.10 с 8 ГБ памяти. Скомпилировал cython с gcc из macports с флагами, указанными в их учебниках -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing
.
Что произойдет, если вы перевернете свои внутренние и внешние петли? – mtrw
Хороший вопрос, он поднимается до ~ 7 мс. Все, что я сделал, это переключить две строки 'for'. – daveydave400
Я предполагаю, что компилятор пытается правильно autovectorize - см. [This] (https://groups.google.com/d/msg/cython-users/LfBH6M7gNTc/B19uFB5YbYYJ). –