Я пишу код numpy для вычисления автокорреляции. Я пытаюсь улучшить производительность своей реализации.
Я пробовал два подхода: матричное умножение на представлениях массива и скалярное произведение на срезах массива в цикле for. К моему удивлению, первый подход кажется намного медленнее.
Функция принимает вектор x
и максимальное смещение k
и возвращает скалярное произведение вектора со смещенным вектором для каждого сдвига i
.
def acorr_aview(x, k):
return np.dot([x[i:-k+i] for i in range(k)], x[:-k])
def acorr_loop(x, k):
return np.array([np.dot(x[i:-k+i],x[:-k]) for i in range(k)])
Я ожидал, что acorr_aview
будет иметь лучшую производительность из-за использования матричного умножения, но, похоже, дело обстоит наоборот.
x = np.random.randn(10000)
k = 100
%timeit acorr_aview(x,k)
%timeit acorr_loop(x,k)
3.32 ms ± 243 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
753 µs ± 33.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Почему acorr_loop
намного быстрее? Спасибо.
Изменить: Для сравнения:
A = np.random.randn(9900,100)
v = np.random.randn(100)
%timeit np.dot(A,v)
%timeit np.array([np.dot(a,v) for a in A])
1.08 ms ± 10.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
12.4 ms ± 243 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)