Да, это ожидаемо.
Первое, что вы должны знать: точка-продукт - это рабочая лошадка numpy-версии, здесь для немного меньших массивов:
>>> def only_dot(x1, x2):
return - 2*np.dot(x1, x2.T)
>>> a = np.zeros((1000,512), dtype=np.float32)
>>> b = np.zeros((100, 512), dtype=np.float32)
>>> %timeit(euclidean_distance_square_einsum(a,b))
6.08 ms ± 312 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit(euclidean_only_dot(a,b))
5.25 ms ± 330 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
то есть 85% времени уходит на это.
Когда вы смотрите на код нумбы, это выглядит как несколько странная / необычная / более сложная версия умножения матрицы на матрицу - можно было увидетьнапример, те же три цикла.
Итак, вы пытаетесь превзойти один из лучших оптимизированных алгоритмов.Вот, например, кто-то пытается это сделать и терпит неудачу .Моя установка использует MKL-версию Intel, которая должна быть более сложной, чем реализация по умолчанию, которую можно найти здесь .
Иногда, после всего веселья, нужно признать, что собственное «заново изобретенное колесо» не так хорошо, как современное колесо… но только тогда можно по-настоящему оценитьего производительность.