C++ c+中map和无序#u map的性能差异+;
我有一个简单的要求,我需要一个类型的地图。然而,我需要最快的理论上可能的检索时间 我使用了来自tr1的map和新提议的无序_map 我发现,至少在解析文件和创建映射时,通过每次插入一个元素可以做到这一点 地图只花了2分钟,而无序地图只花了5分钟 因为它将是Hadoop集群上执行的代码的一部分,并且将包含约1亿个条目,所以我需要尽可能短的检索时间 还有另一个有用的信息: 当前插入的数据(键)是1,2,。。。大约1000万 我还可以强制用户指定最大值并使用上述顺序,这会显著影响我的实现吗?(我听说map是基于rb树的,按递增顺序插入会导致更好的性能(或最差的性能?) 这是密码C++ c+中map和无序#u map的性能差异+;,c++,data-structures,stl,tr1,C++,Data Structures,Stl,Tr1,我有一个简单的要求,我需要一个类型的地图。然而,我需要最快的理论上可能的检索时间 我使用了来自tr1的map和新提议的无序_map 我发现,至少在解析文件和创建映射时,通过每次插入一个元素可以做到这一点 地图只花了2分钟,而无序地图只花了5分钟 因为它将是Hadoop集群上执行的代码的一部分,并且将包含约1亿个条目,所以我需要尽可能短的检索时间 还有另一个有用的信息: 当前插入的数据(键)是1,2,。。。大约1000万 我还可以强制用户指定最大值并使用上述顺序,这会显著影响我的实现吗?(我听说m
map<int,int> Label // this is being changed to unordered_map
fstream LabelFile("Labels.txt");
// Creating the map from the Label.txt
if (LabelFile.is_open())
{
while (! LabelFile.eof() )
{
getline (LabelFile,inputLine);
try
{
curnode=inputLine.substr(0,inputLine.find_first_of("\t"));
nodelabel=inputLine.substr(inputLine.find_first_of("\t")+1,inputLine.size()-1);
Label[atoi(curnode.c_str())]=atoi(nodelabel.c_str());
}
catch(char* strerr)
{
failed=true;
break;
}
}
LabelFile.close();
}
map Label//这是一张无序的地图
fstream LabelFile(“Labels.txt”);
//从Label.txt创建地图
if(LabelFile.is_open())
{
而(!LabelFile.eof())
{
getline(LabelFile,inputLine);
尝试
{
curnode=inputLine.substr(0,inputLine.find_first_of(“\t”);
nodelabel=inputLine.substr(inputLine.find\u优先于(“\t”)+1,inputLine.size()-1);
Label[atoi(curnode.c_str())]=atoi(nodelabel.c_str());
}
捕获(字符*strerr)
{
失败=真;
打破
}
}
不稳定。关闭();
}
P>试探性的解答:在评论和回答之后,我相信动态C++是最好的选择,因为实现将使用密键。感谢无序映射的插入应该是O(1),检索应该大致是O(1),(它本质上是一个哈希表) 因此,您的计时非常不准确,或者您的无序地图的实施或使用出现了一些错误 您需要提供更多信息,可能还需要提供如何使用容器 根据n1836第6.3节,插入/检索的复杂性如下:
你应该考虑的一个问题是,你的实现可能需要不断地<强>重整< /强>结构,如你所说的,你有100MII+项。在这种情况下,当实例化容器时,如果您大致知道将有多少“唯一”元素插入容器中,您可以将其作为参数传递给构造函数,容器将相应地用适当大小的桶表实例化。
无序映射(至少在大多数实现中)提供快速检索,但与地图相比插入速度相对较差。当数据按随机顺序排列时,树通常处于最佳状态,而当数据按顺序排列时,树处于最差状态(您不断地在树的一端插入,增加了重新平衡的频率) 考虑到总共有1000万个条目,您可以分配一个足够大的数组,并获得非常快速的查找——假设有足够的物理内存,它不会导致抖动,但按照现代标准,这并不是一个巨大的内存量 编辑:是的,向量基本上是一个动态数组 Edit2:你添加了一些问题的代码。当(!LabelFile.eof())被破坏时,您的。您通常希望执行类似于while(LabelFile>>inputdata)
的操作。您读取数据的效率也有点低——您显然期望的是两个数字之间用一个标签隔开。在这种情况下,我会编写如下循环:
while (LabelFile >> node >> label)
Label[node] = label;
加载无序_映射的额外时间是由于动态调整数组大小。调整大小计划是在表格超过其负载系数时,将每个单元格的数量增加一倍。因此,从一个空表中,期望得到整个数据表的O(lgn)个拷贝。您可以通过预先调整哈希表的大小来消除这些额外副本。具体地
Label.reserve(expected_number_of_entries / Label.max_load_factor());
除以max_load_因子可以计算出哈希表运行所需的空单元格。问题是我希望扩展实现以处理大约十亿个条目。它将处理十亿个以上节点的网络。地图包含网络中每个节点的标签,代码将以流模式在hadoop上实现。@Mitch:是的,这正是我说的@akshayubha:问题不是条目的数量,而是密钥的密度。如果有10亿个键在10到10亿之间运行,那么一个数组就可以了。如果是10亿个密钥,每个密钥(比如)128位,那么一个数组根本不起作用。是的,根据我在python中的dict经验,哈希表应该比基于二叉树的映射更快,然而,至少对于插入,我发现map比无序的_map快。是的,重新灰化可能会导致插入时间的显著增加,因为我没有提供关于可能的元素数量的任何提示。那么,插入时是否保证为O(1),我说不清?那家伙做错了什么?