String Clojure:为什么字符串上的=和.equals有不同的性能?

String Clojure:为什么字符串上的=和.equals有不同的性能?,string,performance,clojure,String,Performance,Clojure,我是Clojure的新手,有以下简单的功能 (defn find-func [what seq] (filter #(.equals what %) seq) ) 我注意到上面的函数比我用=替换.equals时要慢得多,如下所示: (defn find-func [what seq] (filter #(= what %) seq) ) 当我在JDK1.8.0_25,clojure 1.8上从REPL运行它时,我观察到了这一点: (find-func "10" (map str

我是Clojure的新手,有以下简单的功能

(defn find-func
[what seq]
   (filter #(.equals what %) seq)
)
我注意到上面的函数比我用=替换.equals时要慢得多,如下所示:

(defn find-func
[what seq]
   (filter #(= what %) seq)
)
当我在JDK1.8.0_25,clojure 1.8上从REPL运行它时,我观察到了这一点:

(find-func "10" (map str (range 0 800000)))

为什么会这样?我从另一个stackoverflow-answer()中得知=calls.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 what%)和(clojure.string.ends-with?what%)