在Emacs Lisp中,使用obarray而不是hash-table有什么好处吗?

10
我有一个 Emacs Lisp 程序,需要跟踪一组字符串,用它们进行自动补全并测试其他字符串是否属于该集合。在大多数没有内置“set”类型的语言中,我会使用带有虚拟“t”或“1”值的字典或哈希表,但我想到 Elisp 的“obarray”类型也可以实现这个目的,使用“intern”,“intern-soft”和“unintern”代替“puthash”,“gethash”和“remhash”。
(我知道关于“cl-lib”函数,它们可以将列表作为集合操作,但对于这个问题来说并不特别相关,只需要一个集合成员资格测试)
在现代 Emacs 中,使用 obarray 而不是哈希表是否具有任何优势(例如速度、内存使用或其他方面),还是说除了主符号表之外的 obarray 更像是 Emacs Lisp 有单独的哈希表类型之前的剩余物品?

据我所了解,你只能在新的obarray中intern和unintern值,但是没有办法访问或修改与符号相关联的值。 - Jordon Biondo
1
这不太对——你可以像普通符号一样使用symbol-valueset(let* ((o (make-vector 11 0)) (s (intern "s" o))) (set s 'value) (symbol-value s))value。但在这种情况下,内部化和取消内部化本来就足够了。 - user725091
2
我怀疑在表示集合时,obarray 可能比 hash-table 更不节省空间,因为 hash-table 每个键浪费一个值槽,而 obarray 至少浪费三个,因为每个符号都有值、函数和 plist 槽。 - user725091
1个回答

7
由于两种方法都可以使用,因此在很大程度上是一个品味或性能的问题。
就内存使用情况(以单词计算)而言,obarray 使用固定大小 N 的 1 个数组加上每个条目(大小为 6)一个符号,而哈希表的大小更多或少为每个元素的 5 倍再加上一点。因此,就内存而言,它们差不多。
就速度而言,我不认识任何一个测量过它的人,所以可能也不是一个大问题。
换句话说,这是一个品味问题。对我来说,我更喜欢哈希表,因为它提供了更多的选项;在我看来,obarrays 大部分是历史原因。

谢谢您提供详细的答案。我很惊讶地了解到内存使用量差不多,这点出乎我的意料。 - user725091

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接