我想知道是否有人可以帮助我在Clojure 1.3中使用此代码片段的性能.我正在尝试实现一个简单的函数,它需要两个向量并完成一系列产品. 因此,假设向量是X(大小为10,000个元素)和B(大小为
因此,假设向量是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的函数.
这是代码:它基本上从X获取(计数b)元素,反转它,将*映射到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(范围1 10001))且B为[1 2 3]时,此功能大约需要6秒才能运行.我希望有人可以建议改进运行时间,无论是算法,还是我可能滥用的语言细节.
谢谢!
附:我已经完成了(设置!* warn-on-reflection * true),但没有得到任何反射警告信息.
你不必多次使用计数.下面的代码只计算一次计数(defn filt [b-vec x-vec]
(let [bc (count b-vec) xc (count x-vec)]
(loop [n 0 sig x-vec result []]
(if (= n (- xc bc))
result
(recur (inc n) (rest sig) (conj result (->> sig
(take bc)
(reverse)
(map * b-vec)
(apply +))))))))
(time (def b (filt [1 2 3] (range 10000))))
=> "Elapsed time: 50.892536 msecs"
