如何在cpp中创建一个固定大小(以内存为单位)的哈希表
How to create a fixed size (in terms of memory) hash table in cpp?
我正在处理许多基于某些输入生成浮点的计算。如果我缓存这些数量,似乎可以优化相当多的重复调用。问题是,我不想缓存超过一定量的内存(即10GiB)。有没有一种方法可以在我定义哈希映射时定义它,或者在每次向映射中添加元素时动态测试它?
实现这一点的一种方法是实现LRU缓存("最近最少使用"),它可以让您始终修剪最长时间未引用的元素。对于某些使用模式,这优化了下一个所需项目仍在缓存中的概率。
设计LRU缓存曾经是一个常见的面试问题(也许现在仍然如此),因此有许多so答案等待找到。这个看起来相当完整。
但我不是这样做的。10GiB是大量的内存,你可以在这个空间里保留很多条目。如果您可以消除开销并保留两倍的缓存条目,那么牺牲LRU缓存的精度可能是值得的。消除开销还可以累积地为您节省足够的周期,以抵消使用非最佳缓存修剪策略所需的周期。无论如何,LRU可能不是您的问题的最佳选择。谁知道呢?
有了一个好的哈希函数和一个大的哈希表,您可以使用另一种策略:只需为每个哈希值保留一个条目。该解决方案的优点是几乎为零开销。不需要时间戳,甚至不需要存储桶列表指针。不需要通过链来跟踪条目是否在缓存中;第一个命中是要替换的条目或条目。在实践中,如果你的条目不是太大,那么你可以很容易地将可用的条目数量增加一倍。
对于稍微更精确的解决方案,您可以为每个哈希值保留两个条目,有点像简化的布谷鸟哈希。同样,没有存储开销(只要最终使用了每个哈希值),并且只需要稍微增加查找成本。(实际上很少,因为两个条目都应该在同一个内存缓存行中。)为了获得类似LRU的行为,在这个变体中,如果你找到的缓存条目是哈希值的第二个条目,你可以交换这两个条目。(事实上,在第一个条目不是你需要的条目之后,你交换了两个条目;然后你要么使用要么替换现在是第一个条目的条目。)
C++标准库没有非链式哈希表,但数据结构非常琐碎,几乎不需要库支持。该库可能具有有用的哈希支持。(请参阅boost.hash了解更多散列,如果您的密钥是std::pair
或std::tuple
,则特别有用。)
除此之外,您真正需要的只是一个键值对数组,它的大小可以根据您想要放入缓存的内存量而定。初始化这个数组有一个小问题:它需要初始化为一些东西,通常是默认的键和值构造函数产生的东西。但是,与默认密钥相对应的实际插槽要么需要具有正确的值(不太可能是默认值),要么需要更改为具有不同哈希值的不同密钥。
为每个条目存储一个时间戳,并关注哈希表的capacity
,当它接近边界值时,刷新旧条目。
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- C++中的并发哈希表
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 调整大小和复制哈希表数组中的元素
- 带链接的基本哈希表
- C++哈希表中,两个相同的实现,但一个给出错误
- 如果索引不是整数,我们如何在 C++ 中插入哈希表
- 查找项目在哈希表中的位置
- 为什么C++ STL 哈希表 (unordered_map) 不接受向量作为键
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 使用哈希表设置实现
- 同时写入和读取哈希表
- 在 C++ 中为特定哈希表创建插入函数
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 我的哈希表 C++ 中的内存泄漏
- 在简单的哈希表中解决内存泄漏和语法问题
- 如何在cpp中创建一个固定大小(以内存为单位)的哈希表