Performance 用于实现映射的数据结构,并针对常用键的查找进行了优化

Performance 用于实现映射的数据结构,并针对常用键的查找进行了优化,performance,data-structures,map,Performance,Data Structures,Map,我知道的数据结构,如b-tree或rb-tree,在我一直寻找相同的键时不会改变。我正在寻找一种数据结构,它在运行时对自身进行优化,以便更快地查找常用键。现在我有了这样一个简单的实现: ValueType MyNaiveMap::get(键类型键){ innerMap.addFreq(键); if(key==mostFreqUsedKey1){ 返回值1; }else if(键==MOSTFREQUESEDKEY2){ 返回值2; } 否则{ 返回innerMap.get(key); } }

我知道的数据结构,如b-tree或rb-tree,在我一直寻找相同的键时不会改变。我正在寻找一种数据结构,它在运行时对自身进行优化,以便更快地查找常用键。现在我有了这样一个简单的实现:

ValueType MyNaiveMap::get(键类型键){
innerMap.addFreq(键);
if(key==mostFreqUsedKey1){
返回值1;
}else if(键==MOSTFREQUESEDKEY2){
返回值2;
}
否则{
返回innerMap.get(key);
}
}
在我的情况下,键总是
int

更新:


我忘了提到散列图。因为映射可能会增长到非常大的大小,所以我试图避免在运行时调整O(n)复杂的大小。

您可以在内部跟踪使用最多的X值/键。对您首先检查的这些值进行快速缓存(在检查较大的数据树之前)。跟踪项目被访问/查看的次数。如果在视图中,该项目的查看次数多于列表中的最后一个项目,则可以确定该项目在小列表中的位置。这样,若要查看是否将新项目添加到此快速查找中,只需检查其中的最后一个值,查看是否需要替换它


定期使用最上面的查找值。

如果您提前知道总大小,或者如果由于调整大小而导致的O(n)插入(但在平均情况下仍然是O(1)摊销)对您来说是可以的,那么我认为哈希表是最好的选择。在调整大小时复制整个表的一次性操作也可以通过使用分布在多个操作中

您必须保持哈希表部分为空,以避免冲突,这可能感觉像是在浪费内存。但对于基于树的映射,通常每个项至少有一个额外的指针,这也会“浪费”大量内存。此外,使用哈希表,您可以调整其中有多少保持为空,部分地用性能换取内存(反之亦然)


但也有一种基于树的数据结构,它针对查找最近访问的密钥进行了优化:。它使用旋转将最近使用的关键点保持在接近根的位置,同时仍然保持O(logn)的最坏情况以进行插入和搜索。(这个“摊销”位很重要,有些操作仍然可以是O(n))。

哈希映射呢?你知道散列函数的概念吗?你提前知道地图的大小吗?如果你这样做了,你就可以避免调整大小。我是否正确地理解了你的理解:最坏情况下的平均情况O(logn)(平衡树)比最坏情况下的摊销平均情况O(1)(调整大小哈希映射)更适合你?它在内存中可以增长到100G。我可以提前分配内存以避免调整大小。除此之外,我认为我应该使用hashmap不到50%的容量来获得良好的性能。我会浪费50G内存,对吗?@woodings哈希映射会在空白空间上浪费内存,树会在指针上浪费内存,所以不是说树会减少50%的内存。如何“在内部跟踪使用最多的X个值/键”?我在想这个。但我发现我可能需要一个min/max堆来跟踪使用过的数字。然后每个查找的结果都是O(logN),这与法线贴图相同。