我有许多具有键值模式的数据集 - 即字符串键和指向数据的指针。现在它存储在哈希表中,每个表都有对应于哈希键的插槽数组,并且在碰撞时形成具有冲突的每个槽下的链表(直接链接)。如果重要的话,所有都用C语言实现(并且应该保留在C语言中)。
现在,数据实际上是3种略有不同的数据集类型:
所有课程都必须尽可能快地支持查找,并消耗最少的内存(尽管查找速度比大小更重要)。
所以问题是 - 是否有更好的哈希表结构/实现更适合特定情况?我怀疑第一种情况是链接是最好的,但不确定另外两种情况。
答案 0 :(得分:2)
对于存储在顺序存储器中的密钥,使用二进制甚至线性搜索,那些小(数十个元素)的集合可能是最快的!
显然,关键体必须在顺序存储器中,或者它们的哈希值。但是,如果你可以将它转换成一个或两个L1 cache.lines,它就会飞。
对于较大的哈希,直接链接可能会失去开放寻址?
您可以浏览“cache conscious”哈希表并尝试。
wikipedia文章详细讨论了缓存行,描述了需要考虑的各种权衡因素。
答案 1 :(得分:2)
如果您在散列表中为每个存储桶使用链接列表,则您已经接受了现代CPU上相对较差的性能(链接列表具有较差的位置,因此CPU缓存交互较差)。所以我可能不会担心优化其他特殊情况。但是,如果您想继续沿着您正在使用的路径继续下面,请参阅以下提示:
对于“频繁更改”数据集和“几乎从不更改”的情况,每次从哈希表中读取项目时,将其移动到该存储桶的链接列表链的前面。对于一些更好的想法,本文即使专注于固定大小的密钥,也是一个很好的凝视点Fast and Compact Hash Tables for Integer Keys。
对于'数据集永不改变'的情况,你应该研究完美的哈希生成器。如果你在编译时知道了你的密钥,那么gperf就会有很好的结果。如果您的密钥在运行时才可用,请尝试C Minimal Perfect Hashing Library。