2012-10-26 28 views
2

當我在Clojure中編寫像這樣的函數調用(my-function [a b c])時。 Clojure如何找到我的功能?它是否從全局/每命名空間符號表執行查找?Clojure如何解析名稱?

我假設符號表是作爲一個哈希表來實現的,它爲查找提供了O(1)的時間複雜度。它還需要將函數名稱作爲一個字符串與表中應該花費O(n)個時間(n是符號長度)的符號進行比較。這意味着符號越長,名稱解析就越慢。這是對的嗎?

回答

2

命名空間確實表現爲地圖,你可以看他們直接與ns-map功能:

autotestbed.core> (pprint (take 5 (ns-map *ns*))) 
nil 
([sorted-map                        
    #<[email protected]:                       
    #<core$sorted_map [email protected]>>]             
[read-line                         
    #<[email protected]: #<core$read_line [email protected]>>]          
[re-pattern                        
    #<[email protected]:                       
    #<core$re_pattern [email protected]>>]             
[keyword?                         
    #<[email protected]:                       
    #<core$keyword_QMARK_ [email protected]>>]           
[hta-deploy-cmd                       
    #<[email protected]:                       
    #<core$hta_deploy_cmd [email protected]>>]) 

更具體地說,他們瓦爾映射爲對象。

如果你真的想要一個函數在var中查找,所以變化通過你的程序即時傳播,你可以調用var而不是var在編譯時包含的函數,這會導致查找每一個電話:

(#'foo 4) looks the function up in the var every time 
(foo 4) looks it up in the map once when it's compiled. 
3

Clojure是編譯型語言 - 它直接編譯爲JVM字節碼, 但仍然完全動態的。

- 從http://clojure.org/

編譯頭版指符號已經prehashed爲此您對函數名長度第二條語句是唯一真正在編譯時。另外,如果您擔心每個CPU週期,由於各種原因,JVM/CLR語言不會成爲您的朋友。

3

符號使用interned字符串,因此它們與==比較,而不是.equals。所以即使你說的部分是O(n)也是O(1)。然而,它並不重要,因爲無論如何,所有這些查找(a)都非常快,並且(b)在編譯時發生,而不是在運行時發生。一旦你運行你的程序,所有的函數調用都被解析爲指針解引用或其類似物。