Это связано с реализацией.Ограничивающим шагом является numpy matmul
.Сначала я думал, что SVD является ограничивающим шагом, но он масштабируется линейно (~ 130 мс на итерацию, 1,3 с для пакета из десяти).
Вот некоторые части профилирования:
1 вызов (ваш первый фрагмент)
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.131 0.131 0.131 0.131 linalg.py:1299(svd)
1 0.011 0.011 0.011 0.011 {built-in method numpy.core.multiarray.matmul}
1 0.003 0.003 0.144 0.144 <ipython-input-76-2a63f1c84429>:1(pinv)
1 вызов пакета из 10 (ваш второй фрагмент)
ncalls tottime percall cumtime percall filename:lineno(function)
1 2.952 2.952 2.952 2.952 {built-in method numpy.core.multiarray.matmul}
1 1.265 1.265 1.265 1.265 linalg.py:1299(svd)
1 0.026 0.026 4.266 4.266 <ipython-input-76-2a63f1c84429>:1(pinv)
Возможно, существует внутренняя проблема C-упорядочения (но об этом должны упоминать недавние версии с клочками), или это просто неэффективно в этом случае ... Кратко пытался перейти на интерфейс BLAS напрямуюиспользуя scipy реализацию , но она работает только с двумерными матрицами.Эти проблемы (что matmul медленный) на самом деле были подняты в другом месте .
Итог, сделайте это не векторизованным или попробуйте использовать другие реализации.Иногда самым быстрым способом умножения матриц является использование функций eigen
, но я никогда не пробовал это в многомерной задаче.