当我在Clojure中编写这样的函数调用(my-function [a b c])时。 Clojure如何找到我的功能?它是否从全局/每个命名空间符号表执行查找?
我假设符号表是作为哈希表实现的,它为查找提供了O(1)时间复杂度。它还需要将函数名称作为字符串与表中的符号进行比较,该符号应该花费O(n)时间(n是符号的长度)。这意味着符号越长,名称解析就越慢。这是对的吗?
答案 0 :(得分:3)
的首页开始Clojure是一种编译语言 - 它直接编译为JVM字节码, 但仍然是完全动态的。
编译意味着符号已经预先存在,因此关于函数名长度的第二个语句仅在编译时才为真。此外,如果您担心每个CPU周期,JVM / CLR语言将因各种原因而不是您的朋友。
答案 1 :(得分:3)
符号使用固定字符串,因此它们与==
进行比较,而不是与.equals
进行比较。所以即使你说的部分是O(n)也是O(1)。然而,它几乎不重要,因为所有这些查找(a)无论如何都非常快,并且(b)在编译时发生,而不是运行时。一旦运行程序,所有函数调用都已解析为指针解引用或其类似物。
答案 2 :(得分:2)
命名空间确实表现为地图,您可以使用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>>])
更具体地说,他们将变量映射到对象。
如果你确实想要在它的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.