首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么LLVM选择开放寻址哈希表来实现llvm::StringMap?

为什么LLVM选择开放寻址哈希表来实现llvm::StringMap?
EN

Stack Overflow用户
提问于 2017-07-29 09:22:31
回答 1查看 875关注 0票数 6

许多消息来源说,open-addressing,-- llvm::StringMap中使用的哈希冲突处理方法--不稳定。当负载因子较高(这是可以想象的)时,开放寻址被称为低于链接

但是,如果负载系数较低,将有巨大的内存浪费用于开放寻址,因为我必须在内存中分配Bucket_number *相当大的(记录)字节,即使大多数存储桶不保存记录。

所以我的问题是,为什么LLVM选择开放寻址而不是单独链接呢?这仅仅是因为缓存局部性(记录本身存储在桶中)在速度上的优势吗?

谢谢:)

编辑: C++11标准对std::unordered_setstd::unordered_map的要求意味着链接方法,而不是开放寻址。为什么LLVM选择一个甚至不能满足C++标准的哈希冲突处理方法?对于llvm::StringMap是否有任何特殊的用例可以保证这种偏差?(编辑:此滑动甲板比较了几种LLVM数据结构与STL对应结构的性能)

顺便问一下,另一个问题

llvm::StringMap如何保证键的哈希值在增长时不会被重新计算?手册说:

哈希表增长不会重新计算表中已经存在的字符串的哈希值。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-29 11:36:01

让我们看看实施。在这里,我们看到表存储为指向记录的间接指针的并行数组,以及任何缓存的32位哈希码数组,即结构的单独数组。

有效地:

代码语言:javascript
复制
struct StringMap {
 uint32_t hashcode[CAPACITY];
 StringMapEntry *hashptr[CAPACITY];
};

除了容量是动态的,负载系数似乎保持在容量的37.5%到75%之间。

对于N记录负载因子F,这将为开放地址实现生成N/F指针和N/F整数,而对于等价的链式实现则生成N*(1+1/F)指针和N整数。在典型的64位系统上,开放地址版本的大小在4%到30%之间.

然而,正如您正确地猜测的,这里的主要优势在于缓存效果。除了通过缩小数据来减少争用之外,冲突的过滤归结为对连续32位散列键的线性重新探测,而不检查任何进一步的信息。因此,拒绝碰撞的速度要快得多--在这种情况下,链接必须遵循到可能的非缓存存储中,因此可以使用显著较高的负载因数。另一方面,必须在指针查找表上附加一个可能的缓存缺失,但是这是一个常量,它不会随着负载的减少而减少,相当于一个链式碰撞。

有效地:

代码语言:javascript
复制
StringMapEntry *StringMap::lookup(const char *text) {
    for(uint32_t *scan = &hashcode[hashvalue % CAPACITY]; *scan != SENTINEL; ++scan) {
        uint32_t hash_value = hash_function(text);
        if(hash_value == *scan) {
            StringMapEntry *entry = p->hashptr[scan - hashcode];
            if(!std::strcmp(entry->text, text))
                return entry;
            }
        }
    }
}

加上诸如包装之类的微妙之处。

至于您的第二个问题,优化是预计算和存储散列键。这浪费了一些存储空间,但是防止了检查潜在的长可变长度字符串的昂贵操作,除非匹配几乎是确定的。在退化的情况下,复杂的模板名称损坏,可能是数百个字符。

RehashTable中的进一步优化是使用2的幂,而不是素表大小。这确保了表的增长会有效地带来额外的哈希码位,并将加倍的表去交织成两个连续的目标数组,从而有效地使操作成为一个对缓存友好的线性扫描。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45387613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档