Clojure:为什么=和.equals字符串有不同的表现?
问题描述:
我相对新的Clojure并具有下列简单的函数Clojure:为什么=和.equals字符串有不同的表现?
(defn find-func
[what seq]
(filter #(.equals what %) seq)
)
我注意到,上述功能是比当我代替.equals与=这样显著较慢:
(defn find-func
[what seq]
(filter #(= what %) seq)
)
我观察到当我从REPL在jdk 1.8.0_25上运行它时,clojure 1.8:
(find-func "10" (map str (range 0 800000)))
这是为什么?我虽然从另一个stackoverflow的答案(Stack overflow question)that =调用.equals,所以不应该有任何性能差异。从那时起是否进行了优化?谢谢你的澄清。
答
的问题是,你的第一个find-func
使用反射,而你的第二个没有:
(set! *warn-on-reflection* true)
(defn find-func [what seq]
(filter #(.equals what %) seq))
;; Reflection warning, foo.clj:2:12 - call to method equals can't be resolved (target class is unknown).
(defn find-func [what seq]
(filter #(= what %) seq))
如果添加了一丝类型,以避免反射,.equals
会比=
快:
(defn find-func [^Object what seq]
(filter #(.equals what %) seq))
Clojure应该可以自己弄清楚,但由于某种原因,它不能。
最有可能非常连接。我发现相同的性能差异适用于(.endsWith%)和(clojure.string.ends-with?what%) – Vojta