我想知道是否有人可以帮助我在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"