2015-05-06 68 views
2

下面是代碼:爲什麼不鍵入暗示提高此功能的性能?

(defn first-char-of-either [^String a ^String b] 
    (.substring (or a b) 0 1)) 
(defn first-char-of-either1 [^String a ^String b] 
    (.substring ^String (or a b) 0 1)) 
(time (dorun (repeatedly 1000000 #(first-char-of-either nil "abcde")))) 
(time (dorun (repeatedly 1000000 #(first-char-of-either1 nil "abcde")))) 

在這種情況下不會提高性能,在所有類型的提示,爲什麼呢?

+0

不知道,但也許是因爲'substring'是一個'java.lang.String'方法,因此編譯器已經知道它是一個字符串? – m0skit0

+1

編譯器無法保證在運行時可能存在什麼類和方法,所以它不知道'substring'是一種只存在於String中的方法。 –

回答

7

僅當Clojure編譯器無法推斷類型時,類型提示纔會提高運行時性能。在first-char-of-either函數中,(or a b)表達式的or是一個宏,它被擴展爲這樣。

(let* [or__3975__auto__ a] (if or__3975__auto__ or__3975__auto__ b)) 

因爲Clojure的編譯器知道這兩個ab有型String,它可以推斷(or a b)的結果類型,無需額外類型提示到(or a b)。總之,您不必在Clojure編譯器可以推斷類型的地方添加類型提示。您可以通過打開*warn-on-reflection*來檢查Clojure編譯器是否可以成功推斷類型。