2016-08-13 78 views
3

我相對新的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,所以不應該有任何性能差異。從那時起是否進行了優化?謝謝你的澄清。

+0

最有可能非常連接。我發現相同的性能差異適用於(.endsWith%)和(clojure.string.ends-with?what%) – Vojta

回答

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)) 

如果添加了一絲類型,以避免反射,.equals會比=快:

(defn find-func [^Object what seq] 
    (filter #(.equals what %) seq)) 

Clojure應該可以自己弄清楚,但由於某種原因,它不能。

相關問題