Clojure如何解析名称?

Clojure如何解析名称?,clojure,Clojure,当我在Clojure中编写这样的函数调用时(我的函数[ABC])。Clojure如何找到我的功能?它是否从全局/每个命名空间符号表执行查找 我假设符号表是作为哈希表实现的,它为查找提供了O(1)时间复杂度。它还需要将函数名作为字符串与表中的符号进行比较,这需要O(n)个时间(n是符号的长度)。这意味着符号越长,名称解析越慢。它是否正确?名称空间实际上表现为映射,您可以使用ns map功能直接查看它们: autotestbed.core> (pprint (take 5 (ns-map *n

当我在Clojure中编写这样的函数调用时(我的函数[ABC])。Clojure如何找到我的功能?它是否从全局/每个命名空间符号表执行查找


我假设符号表是作为哈希表实现的,它为查找提供了O(1)时间复杂度。它还需要将函数名作为字符串与表中的符号进行比较,这需要O(n)个时间(n是符号的长度)。这意味着符号越长,名称解析越慢。它是否正确?

名称空间实际上表现为映射,您可以使用
ns map
功能直接查看它们:

autotestbed.core> (pprint (take 5 (ns-map *ns*)))
nil
([sorted-map                                                                                               
  #<Var@6899a7ce:                                                                                          
    #<core$sorted_map clojure.core$sorted_map@5875c014>>]                                                  
 [read-line                                                                                                
  #<Var@1de9e86e: #<core$read_line clojure.core$read_line@57c00972>>]                                      
 [re-pattern                                                                                               
  #<Var@74064c7b:                                                                                          
    #<core$re_pattern clojure.core$re_pattern@37d02427>>]                                                  
 [keyword?                                                                                                 
  #<Var@4798088a:                                                                                          
    #<core$keyword_QMARK_ clojure.core$keyword_QMARK_@630b813f>>]                                          
 [hta-deploy-cmd                                                                                           
  #<Var@7a7bce95:                                                                                          
    #<core$hta_deploy_cmd autotestbed.core$hta_deploy_cmd@6a6a782d>>])
Clojure是一种编译语言-它直接编译为JVM字节码, 但仍然是完全动态的

-摘自


编译意味着符号已经预灰化,因此关于函数名长度的第二条语句只有在编译时才为真。另外,如果您关心每个CPU周期,JVM/CLR语言将不会是您的朋友,原因有很多。

符号使用内部字符串,因此它们与
=
比较,而不是与
.equals
比较。所以即使你说的部分是O(n)也是O(1)。然而,这并不重要,因为所有这些查找(a)无论如何都非常快,(b)发生在编译时,而不是运行时。一旦你运行了你的程序,所有的函数调用都被分解成指针解引用或者类似的

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