存储密钥对的最快且内存最有效的方法<int,int =“”> value int

时间:2018-01-14 15:27:24

标签: c++ performance memory-management hashmap std-pair

我有大量具有以下结构的数据:

(ID1, ID2) -> value  
(12, 243) -> 7712  
(311, 63) -> 123  
...

纯二进制未压缩数据大约只有2.5 GiB,所以它基本上应该适合我16GiB的RAM。但是,在分配许多小对象时,我遇到了分配开销问题 以前我将所有具有相同ID1的值存储在同一个对象中,因此对象内的列表只存储了ID2和值。这种方法对于它所用的实际上下文也很有用。

class DataStore {
    int ID1;
    std::unordered_map<int, int> data; //ID2 -> value
}

问题是,加载许多这些对象(数百万个)似乎有巨大的开销......简单地以这种方式加载所有数据显然超出了我的RAM - 无论我是否使用

DataStore* ds = new DataStore();

或只是

DataStore ds = DataStore();

用于将它们存储在矢量或其他类型的容器中。

将它们存储在嵌套的哈希映射中可以减少开销(现在它适合我的RAM),但它仍然只有9,2GiB - 我不知道这是不是可以减少...

所以,我试过

google::sparse_hash_map<int, google::sparse_hash_map<int, int>> 

和std :: map,std :: unordered_map,但google :: sparse_hash_map目前是提到的9,2GB最好的......

我也试过

std::map<std::pair<int, int>, int> 

结果更糟。
我尝试将long中的两个键组合在一起移动,但插入性能因为某种原因而非常慢......所以我不知道内存使用情况会如何,但它太慢了,即使使用google sparsehash也是如此...

我读了一些关于池分配器的事情,但是我不确定我是否可以在同一个池中分配多个容器,这是唯一有用的场景,我想......我也不是确定使用哪个池分配器 - 如果这是一个好主意 - 建议?

查找性能非常重要,因此向量不是最佳的...插入性能也不应该太差...

编辑:

boost :: flat_map可以像我需要的那样具有内存效率,但插入速度非常慢......我试过了两个

boost::container::flat_map<std::pair<unsigned int, unsigned int>, unsigned int>
boost::container::flat_map<unsigned int, boost::container::flat_map<unsigned int, unsigned int>>

也许我只能有良好的插入&amp;查找性能或内存效率...

EDIT2:

google::sparse_hash_map<std::pair<unsigned int, unsigned int>, unsigned int, boost::hash<std::pair<unsigned int, unsigned int>>>

使用大约6,3GiB,一些优化只有4,9GiB(值(123,45)和(45,123)应该相等:)非常好 - 谢谢!

EDIT3:

在我的上下文中,因为我现在使用对作为键而没有嵌套的哈希映射,所以对于我的大部分目的来说它都是无用的(我经常需要做像&#34这样的事情;得到包含ID 12231的所有对 - 所以我必须遍历所有条目...一个特定的条目是好的,但是一对半#&#34;不好搜索。另一个索引消耗几乎与嵌套的hastmap解决方案一样多的内存...我将简单地坚持我的旧方法(序列化数据并将其保存在某个LevelDB中),因为它对于我需要的特定部分来说速度非常快,大约50ms,相比之下整个迭代大约需要2秒:)但是谢谢所有建议:)

0 个答案:

没有答案