gpt4 book ai didi

java - Clojure 性能优化与等效 Java

转载 作者:行者123 更新时间:2023-12-02 09:18:24 26 4
gpt4 key购买 nike

加速此功能的最佳简单方法是什么?根据 Criterium,Java 中的等效代码快了近 50 倍。

我敢打赌,如果我使用 java 数组并减少装箱量,这都会有所帮助,但我想我应该先在这里发帖,看看我是否犯了任何可以轻松修复的基本错误。注意我已经为 Clojure 指出了 (double...),这极大地提高了性能,但仍然不像 Java。我还首先在函数内使用 (double-array...) 而不是使用 (vec ...) 转换了 seq,这也提高了性能,但同样,与 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 都是 seq,每个包含 200 个 Double。在 java 版本中,它们作为 double[] args 传递。

最佳答案

使用 (double 0) 不会带来直接指定 0.0( double 文字)无法获得的性能优势。

如果您将 mamb 作为 double-array 传递,并将参数提示为 double,您将获得显着更好的性能,不要通过vec将它们转换为 vector ,并使用aget来进行元素查找。这应该会让您获得非常接近 Java 代码性能的结果。

如果您使用 double 组作为函数参数,则不需要 let block 内的 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))))))

关于java - Clojure 性能优化与等效 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27735980/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com