我需要读取一个非常大,高度相互关联的数据集,数据相当本地化,并且读取相当昂贵。具体做法是:
从问题的知识和分析,我相信在程序中引入缓存将有很大帮助。我想要做的是创建一个缓存,其中包含N个大块的X兆内存(N和X可配置,因此我可以调整它),我可以先检查,然后再映射另一部分内存。此外,缓存中的某些内容越长,我们在短期内请求内存的可能性就越小,因此最旧的数据将需要过期。
毕竟,我的问题很简单:哪种数据结构最适合实现这种性质的缓存?
我需要非常快速的查找,以查看给定地址是否在缓存中。随着缓存的每次“遗漏”,我都希望使其中最老的成员到期,并添加一个新成员。但是,我打算尝试调整它(通过更改缓存的数量),使70%或更多的读取次数达到。
我目前的想法是使用AVL树(用于搜索/插入/删除的LOG2 n)将是最安全的(没有退化情况)。我的另一个选择是稀疏哈希表,在最好的情况下查找将是O(1)。从理论上讲,这可能会退化为O(n),但实际上我可以保持较低的碰撞。这里需要关注的是查找和删除哈希表中最旧的条目需要多长时间。
有没有人对这里最好的数据结构有什么想法或建议?为什么?
答案 0 :(得分:3)
答案 1 :(得分:2)
如果你的算法的60%是I / O,我建议实际的缓存设计并不那么重要 - 任何类型的缓存都可以大幅加速。
但是,设计很大程度上取决于您用来访问块的数据。 String,int等。如果你有一个int,你可以在一个链表中做一个hashmap,在高速缓存未命中时删除,擦除然后在高速缓存命中时按下它。
在许多实现中,以不同的名称(最常见的是无序映射)提供了散列图。 Boost有一个,TR1中有一个,等等.hash_map的一大优点是随着数字的增加,性能损失减少,关键值的灵活性也更高。
答案 2 :(得分:2)
将缓存放入两个排序的树中(AVL或任何其他合理平衡的树实现都很好 - 最好使用库中的一个而不是创建自己的树)。
一棵树应按文件中的位置排序。这使您可以执行log(n)查找以查看缓存是否存在。
另一棵树应该按照使用的时间排序(可以用每次使用时增加1的数字表示)。使用缓存块时,将其删除,更新时间并再次插入。这也将采用log(n)。当您错过时,删除树的最小元素,并将新块添加为最大。 (不要忘记同时删除/添加该块到文件中的位置树。)
如果您的缓存中没有很多项目,那么最好还是将所有内容存储在已排序的数组中(使用插入排序添加新元素)。将16个项目向下移动到数组中的一个位置非常快。