加速这个功能的最简单的方法是什么?根据Criterium的说法,java中的等效代码快近50倍。
我打赌如果我使用了java并减少了所有这些都有帮助的装箱量,但我想我应该先在这里发布,看看我犯的任何基本错误是否可以很容易地修复。注:我已经指出(加倍.)这大大提高了性能,但仍然不像Java。我还首先使用(双数组.)转换了seq。而不是使用(vec .)内部的函数,这也提高了性能,但同样,不像Java。
(defn cosine-similarity [ma mb]
(let [va (vec ma), vb (vec mb)]
(loop [p (double 0)
na (double 0)
nb (double 0)
i (dec (count va))]
(if (neg? i)
(/ p (* (Math/sqrt na) (Math/sqrt nb)))
(let [a (double (va i))
b (double (vb i))]
(recur (+ p (* a b))
(+ na (* a a))
(+ nb (* b b))
(dec i)))))))请注意,ma和mb都是seqs,每个包含200个双倍。在java版本中,它们作为double[] args传递。
发布于 2015-01-02 00:39:52
使用(double 0)没有从直接指定0.0 (双文本)中获得的性能好处。
如果将ma和mb作为double-array传递,并提示args为doubles,不要通过vec将它们转换为向量,并使用aget进行元素查找,您将获得更好的性能。这将给您留下一些与java代码性能非常接近的东西。
如果使用双数组作为函数args,则不需要let块中的double调用。
最终结果应该如下所示:
(defn cosine-similarity [^doubles ma ^doubles mb]
(loop [p 0.0
na 0.0
nb 0.0
i (dec (count va))]
(if (neg? i)
(/ p (* (Math/sqrt na) (Math/sqrt nb)))
(let [a (aget va i)
b (aget vb i)]
(recur (+ p (* a b))
(+ na (* a a))
(+ nb (* b b))
(dec i))))))发布于 2015-01-02 00:49:37
你试过加法了吗?
(set! *unchecked-math* true)因为你知道范围,你可能会用它来获得额外的速度。
编辑:@噪音匠是正确的,双数组和输入输入会产生巨大的变化。
Edit2:在亚历克斯·米勒的评论之后,获得了惊人的成绩。
(set! *unchecked-math* true)
(defn ^double cosine-similarity
[^doubles va ^doubles vb]
(loop [p 0.0
na 0.0
nb 0.0
i (dec (alength va))]
(if (< i 0)
(/ p (* (Math/sqrt na) (Math/sqrt nb)))
(let [a (aget va i)
b (aget vb i)]
(recur (+ p (* a b))
(+ na (* a a))
(+ nb (* b b))
(dec i))))))
(defn rand-double-arr [n m]
(double-array
(take n (repeatedly #(rand m)))))
(def ma (rand-double-arr 200 10000))
(def mb (rand-double-arr 200 10000))
; using do times
(dotimes [_ 30] (time (cosine-similarity ma mb)))
; ...
; "Elapsed time: 0.003537 msecs"
; using criterium: [criterium "0.4.3"]
(use 'criterium.core)
(quick-bench (cosine-similarity ma mb))
;
; Execution time mean : 2.072280 µs
; Execution time std-deviation : 214.653997 ns
; Execution time lower quantile : 1.765412 µs ( 2.5%)
; Execution time upper quantile : 2.284536 µs (97.5%)
Overhead used : 6.128119 ns第一个版本在500~1000毫秒范围内。
https://stackoverflow.com/questions/27735980
复制相似问题