哈希表的随机访问

问题描述

我有一个SBCL哈希表,其中哈希键是符号。如果哈希表是由eq组成的,则调用gethash会随机访问元素吗?我知道这些细节是特定于实现的,但是到目前为止,我还无法在文档中找到明确的答案。

解决方法

我假设(也是从评论中的讨论中得出),通过“给予随机访问”,您意味着哈希表中元素的分布将是随机的,因此将具有O(1)访问性能。答案是肯定的。当分布偏斜时,会有一些退化的情况,例如这种(Why does `sxhash` return a constant for all structs?),但是绝对不是这样。对于eq比较,实现将使用对象的地址进行哈希处理。对于SBCL,这是实际代码:

(defun eq-hash (key)
  (declare (values hash (member t nil)))
  ;; I think it would be ok to pick off SYMBOL here and use its hash slot
  ;; as far as semantics are concerned,but EQ-hash is supposed to be
  ;; the lightest-weight in terms of speed,so I'm letting everything use
  ;; address-based hashing,unlike the other standard hash-table hash functions
  ;; which try use the hash slot of certain objects.
  (values (pointer-hash key)
          (sb-vm:is-lisp-pointer (get-lisp-obj-address key))))

但是,您也可以选择使用eql哈希表(我建议:仅为那些知道自己在做什么的人使用eq):)。对于这种情况,SBCL具有特殊功能来对符号进行哈希处理:symbol-hash。我认为其他实现也可以做类似的事情,因为符号可能是哈希表键的最常见类型。

,

根据设计,哈希表使O(1)可以访问和更新其元素。它不是特定于实现的。

由于散列的工作方式不同于比较标准CL中的散列表,因此限制为eqeql(默认),equalequalp。实际上,这仅意味着其中之一认为是真实的两个值的哈希值将具有相同的哈希值。 SBCL允许您定义哈希函数,但不能移植。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...