用C ++

时间:2015-05-07 09:41:53

标签: c++ c++11

我将以下数据存储在SSD上的文件中(数据大小为2GB)。我想在内存中加载这些数据,这样给定Number1和Number2,我能够检索与之关联的列表。

Number1  Number2  List(in sorted order. contains maximum 1000 elements)
12       1        5585,5587,5589,5590,5594,5597,5610,5615,5618,5619       
12       2        4561,4789,4980,5001,5008,5010,5100,5150,5240,5250
12       3        3010,3223,3225,3278,3890,4890,5001

13       1        3585,3587,3589,3590,3594,3597,3610,3615,3618,3619       
13       2        14561,14789,14980,15001,15008,15010,15100,15150,15240,15250
13       3        23010,23223,23225,23278,23890,24890,25001

14       1        1585,1587,1589,1590,1594,1597,1610,1615,1618,1619       
14       2        561,789,980,1001,1008,1010,1100,1150,1240,1250
14       3        1010,1223,1225,1278,1890,1891,15001
14       4        4,89,928,3958,95859

我将这些数据存储在std::map<unsigned,std::map<unigned,vector<unsigned>>>中给定的Number1和Number2我想要检索与之关联的列表。

然而,事实证明,从文件中读取此数据并将其存储在64 GB服务器上的std::map<unsigned,std::map<unigned,vector<unsigned>>>内存中需要5个小时。是否有一些我可以使用的其他数据结构,给定Number1和Number2我可以有效地检索与之关联的列表。此外,数据结构不应花费太多时间来加载这些数据。 Number2(给定Number1)的范围也始终为1到10.

我正在使用:g ++(GCC)4.8.2 20140120(Red Hat 4.8.2-15)

3 个答案:

答案 0 :(得分:2)

以下是我的建议:

  1. 最佳解决方案是将数据存储在数据库中。在过去的几十年里,公司在这方面做得很好,实施自己的数据库并没有多大意义。只需使用其中一个。如果你真的希望数据完全加载到内存中,你可以使用MySQL的MEMORY引擎:
  2. https://dev.mysql.com/doc/refman/5.5/en/memory-storage-engine.html

    1. 如果Number1和Number2是整数,那么也许你可以将它们组合成一个64位长的整数,然后使用它是你字典中的关键字。

    2. 在这种情况下使用std :: map可能有点慢,因为它在内部实现为自平衡二叉树,因此其操作为O(log(n))。如果您可以使用C ++ 11功能,那么您可以使用stl :: unordered_map作为哈希实现,因此操作是O(1)。

答案 1 :(得分:2)

您可以尝试使用boost :: multi_index_container。这是an example 还有很多other examples,您也可以查看them。我只知道这些东西,并希望它有所帮助。

答案 2 :(得分:2)

这是一个有趣的问题,像往常一样,你必须妥协速度和空间。 你的解决方案在这两方面都非常糟糕,因为使用地图你的内存将会被如此多的数据分割,并且查找将在对数范围内,这不是最佳的。

你可以尝试:

struct Value{
  std::vector<int> _values;
}
std::unordered_map<std::uint64_t, Value> values;

无序地图的关键字是Number1 * 100 + Number2