當我在Clojure中編寫像這樣的函數調用(my-function [a b c])時。 Clojure如何找到我的功能?它是否從全局/每命名空間符號表執行查找?Clojure如何解析名稱?
我假設符號表是作爲一個哈希表來實現的,它爲查找提供了O(1)的時間複雜度。它還需要將函數名稱作爲一個字符串與表中應該花費O(n)個時間(n是符號長度)的符號進行比較。這意味着符號越長,名稱解析就越慢。這是對的嗎?
當我在Clojure中編寫像這樣的函數調用(my-function [a b c])時。 Clojure如何找到我的功能?它是否從全局/每命名空間符號表執行查找?Clojure如何解析名稱?
我假設符號表是作爲一個哈希表來實現的,它爲查找提供了O(1)的時間複雜度。它還需要將函數名稱作爲一個字符串與表中應該花費O(n)個時間(n是符號長度)的符號進行比較。這意味着符號越長,名稱解析就越慢。這是對的嗎?
命名空間確實表現爲地圖,你可以看他們直接與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.
Clojure是編譯型語言 - 它直接編譯爲JVM字節碼, 但仍然完全動態的。
編譯頭版指符號已經prehashed爲此您對函數名長度第二條語句是唯一真正在編譯時。另外,如果您擔心每個CPU週期,由於各種原因,JVM/CLR語言不會成爲您的朋友。
符號使用interned字符串,因此它們與==
比較,而不是.equals
。所以即使你說的部分是O(n)也是O(1)。然而,它並不重要,因爲無論如何,所有這些查找(a)都非常快,並且(b)在編譯時發生,而不是在運行時發生。一旦你運行你的程序,所有的函數調用都被解析爲指針解引用或其類似物。