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

Voj*_*jta 3 string performance clojure

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

(defn find-func
[what seq]
   (filter #(.equals what %) seq)
)
Run Code Online (Sandbox Code Playgroud)

我注意到上面的函数明显慢于我用.替换.equals = =

(defn find-func
[what seq]
   (filter #(= what %) seq)
)
Run Code Online (Sandbox Code Playgroud)

我在jdk 1.8.0_25,clojure 1.8上从REPL运行时观察到它:

(find-func "10" (map str (range 0 800000)))
Run Code Online (Sandbox Code Playgroud)

为什么会这样?我虽然从另一个stackoverflow回答(堆栈溢出问题)=调用.equals所以不应该有任何性能差异.从那时起就优化了吗?感谢您的任何澄清.

Sam*_*tep 6

问题是你的第一个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))
Run Code Online (Sandbox Code Playgroud)

如果添加类型提示以避免反射,.equals则会比=以下更快:

(defn find-func [^Object what seq]
  (filter #(.equals what %) seq))
Run Code Online (Sandbox Code Playgroud)

Clojure应该能够自己解决这个问题,但由于某种原因它不会.