Мне было интересно, может ли кто-нибудь помочь мне с производительностью этого фрагмента кода в Clojure 1.3.Я пытаюсь реализовать простую функцию, которая принимает два вектора и делает сумму продуктов.
Итак, предположим, что векторами являются X (размер 10 000 элементов) и B (размер 3 элемента), а сумма произведений хранится в векторе Y, математически это выглядит так:
Y0 = B0 * X2 + B1 * X1 + B2 * X0
Y1 = B0 * X3 + B1 * X2 + B2 * X1
Y2 = B0 * X4 + B1 * X3 + B2 *X2
и т. Д. ...
В этом примере размер Y в конечном итоге составит 9997, что соответствует (10 000 - 3).Я настроил функцию для принятия любого размера X и B.
Вот код: он в основном берет (count b)
элементов за один раз из X, обращает его, отображает *
на B и суммысодержимое результирующей последовательности для создания элемента Y.
(defn filt [b-vec x-vec]
(loop [n 0 sig x-vec result []]
(if (= n (- (count x-vec) (count b-vec)))
result
(recur (inc n) (rest sig) (conj result (->> sig
(take (count b-vec))
(reverse)
(map * b-vec)
(apply +)))))))
Если X равен (vec (range 1 10001))
, а B равно [1 2 3]
, эта функция запускается приблизительно за 6 секунд.Я надеялся, что кто-то может предложить улучшения во время выполнения, будь то алгоритмическая или, возможно, языковая деталь, которой я мог бы злоупотреблять.
Спасибо!
PS Я сделал (set! *warn-on-reflection* true)
, но донне получите никаких предупреждений об отражении.