请在2024年Clojure状态调查!中分享您的想法。

欢迎!有关如何使用此网站的更多信息,请参阅关于页面。

+1
编译器

Clojure中的关键字进行缓存和内部化,因此

(identical? :a :a)

返回true。但符号不是

(identical? 'a 'a)

返回false。

为什么?

2 个答案

+4

选出最佳答案
 
最佳答案

符号是上下文相关的,相同符号的不同实例可以具有不同的元数据。

元数据是有状态的,与内部化的概念相矛盾。关键字没有元数据,但具有快速的标识符等价语义。
0

我认为答案的一部分在于,关键字是为了在 maps(也许还有其他数据结构)中更有效地使用内存和键查找性能而被内联的,因为 Clojure 中的 = 在大多数情况下首先执行 identical? 的快速检查,如果它们相同则返回 true。这使得它们在用作 map 键时,与其他值相比具有更好的性能特点,因为这通常在 Clojure 程序中很常见。

话虽如此,关键字内联确实会在它们首次内联时产生性能成本。对于关键字来说,这通常不是一个大问题,尤其对于大多数 Clojure 程序中使用的相对较少的关键字集合而言。它曾经是那些阅读大量 JSON 文件并大规模将 JSON key 字符串转换为 Clojure 关键字的用户的性能问题。Clojure 在过去对这些情况进行了改进。我目前没有 JIRA 工单,但如果有兴趣查找那些工单,我可以找到它们。

符号并不是为了这些用例而进行性能优化的,如果你尝试将它们用作 maps 的键,则性能会略差,但我相信这也避免了在遇到新符号时的内联性能成本。

在 Common Lisp 中有关于这种相似行为的记录,也可能在其他 Lisp 家族语言中有。

...