Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内存效率映射<;配对<;int,int>;,设置<;int>&燃气轮机;可供替代的_C++_Dictionary_Hashmap_Minhash - Fatal编程技术网

C++ 内存效率映射<;配对<;int,int>;,设置<;int>&燃气轮机;可供替代的

C++ 内存效率映射<;配对<;int,int>;,设置<;int>&燃气轮机;可供替代的,c++,dictionary,hashmap,minhash,C++,Dictionary,Hashmap,Minhash,我有大量(15亿)的整数对,每个整数对都与一个文档ID关联。我现在的目标是搜索具有相同整数对的文档 我的第一个想法是使用散列映射(std::map),使用对值作为键,文档ID作为关联值,即map 例如: Document1 - pair1: (3, 9) - pair2: (5,13) Document2 - pair1: (4234, 13) - pair2: (5,13) map<pair<int,int>, unordered_set<int>

我有大量(15亿)的整数对,每个整数对都与一个文档ID关联。我现在的目标是搜索具有相同整数对的文档

我的第一个想法是使用散列映射(
std::map
),使用对值作为键,文档ID作为关联值,即
map

例如:

Document1

 - pair1: (3, 9)
 - pair2: (5,13)

Document2

 - pair1: (4234, 13)
 - pair2: (5,13)

map<pair<int,int>, unordered_set<int>> hashMap
hashMap[{3, 9}].insert(1)
hashMap[{5, 13}].insert(1)

hashMap[{4234, 13}].insert(2)
hashMap[{5, 13}].insert(2)

我现在的问题是,这占用了大量内存,超过了我可用的24GB RAM。因此,我需要一个具有良好性能的替代品来进行插入和查找,以适应我的记忆。理论上,我使用的是
1500000000*3(PairVal1,PairVal2,documentid)*4(字节/整数)=18GB
,而不考虑间接成本。那么有什么好办法解决我的问题吗?

你能使用文件系统吗

命名目录后的第一个整数,创建文本文件中的每一个命名为第二个整数,文本文件的每一行都可以是一个文档ID


在所有I/O上,您肯定会遭受严重的速度损失。请尽可能快地使用磁盘。随着目录名、文件名和文件内容变成ascii文本而不是二进制整数,存储需求也将显著增长。

减少空间的一种解决方案是使用
std::map
use
std::unordered\u map

要将
std::pair
转换为
int
,必须使用配对功能,例如:

Document1

 - pair1: (3, 9)
 - pair2: (5,13)

Document2

 - pair1: (4234, 13)
 - pair2: (5,13)

map<pair<int,int>, unordered_set<int>> hashMap
hashMap[{3, 9}].insert(1)
hashMap[{5, 13}].insert(1)

hashMap[{4234, 13}].insert(2)
hashMap[{5, 13}].insert(2)

很明显,你只能在配对中使用较小的数字

两个最大16位有符号整数(32767,32767)的映射将为2147418112,这刚好低于有符号32位整数的最大值

其他选项是在B-Tepe中创建自己的索引器,或者使用开源搜索引擎库,比如C++编写的,使用速度快,使用方便。 Xapian是一个适应性很强的工具包,允许开发人员轻松地将高级索引和搜索功能添加到自己的应用程序中


这可能是SQLite、BerkeleyDB或Tokyo Cabinet等嵌入式数据库的工作


如果您使用的数据量超过了RAM,那么您确实需要一些可以从磁盘工作的东西。

std::map不是散列映射,您可能需要std::unordered\u mapI不能说明它的效率,但是您可以看看stxxl来了解这类问题。如果
集合
中的文档数很小,则可以用
std::vector
替换它。30亿个整数必然需要大量空间。在您添加文档ID集之后,我不确定您是否可以通过更改容器来节省大量空间。@DieterLücking使用带有15亿条记录的
无序_map
,已经需要50 GB,而这甚至还没有保存文档ID。因此,
unordered_map
map
的开销太大了,我在某个地方读到,每个哈希映射条目存储了额外的32个字节,这就是问题所在。如果您正在使用磁盘,为什么不只使用交换文件或
mmap()
支持的分配器呢。这应该比每个条目的文件开销低得多。@joelw因为
mmap()
通常比低级
read()
/
write()
调用慢得多@当此解决方案不是低级的
read()
/
write()
时,每次读取都将使用
open()
/
close()
对进行包装。我已经考虑过了,问题是每个对的值可能在0到100万之间。我想我需要100万*100万个映射可能性,超过了
unsigned int
范围,而
unsigned long long
变量将再次占用8个字节。我正计划这样做,但根据我的数据库经验,事后来看,性能并不是很好,我不想匆忙做任何最终不起作用的事情。因此,我不确定插入新对需要多长时间,在检查该对是否已经存在之前。我可以想象,拥有15亿行,这种操作将非常昂贵。“你有这方面的经验吗?”玛达。几年前,我用东京橱柜做了类似的事情,它的速度是每秒50000次。