我试图比较填充地图的两种技术,一种是迭代器,另一种是没有。我听说迭代器让它变得更快,但是怎么样?
//With Iterator
map<int, int>::iterator insert = fibHash.begin();
fibHash.insert(begin, pair<int, int> (n, fib_val));
//Without iterator
fibHash.insert(pair<int, int> (n, fib_val));
答案 0 :(得分:4)
首先,您必须记住std::map
是一个有序结构,因此您不能将元素放在任意位置。根据{{3}}(满足某些条件的较小关系),某个元素只能放在相对于其他元素的某个位置。
第一个变量将迭代器作为元素的良好位置的提示,并且只有在插入发生在输入迭代器旁边时才使插入更快(分摊常量时间)。否则,复杂性与第二个变量(对数)相同。
第一个变体使用第一个参数作为提示,并尝试插入。如果提示是好的,则需要较少的比较来找到正确的插入位置。
答案 1 :(得分:4)
第一种形式,你提供一个迭代器, potential 在运行时更快 - 但只有你选择一个好的迭代器,即使那时你的实现使用了提示。您发送给insert
的迭代器只是一个提示。 insert
不一定在那里插入元素,因为map
是一个已排序的容器。相反,迭代器可以被实现用作查找将插入元素的位置的起点。
所以,如果你传递一个精心选择的迭代器(begin()
通常不会),使用带有提示迭代器的insert
版本,你理论上可以接近摊销的常数时间插入,而使用非提示版本,您正在查看O(log n)
插入。
答案 2 :(得分:0)
添加到已经说过的内容:如果您关注速度,还可以考虑使用新的C ++ 11方法std::map::emplace和std::map::emplace_hint将元素插入std::map
。 emplace不会将键/值对的副本传递给容器,而是仅传递用于在正确位置创建该对就地的参数。这可以为您节省昂贵的副本(尽管在您的int,int示例中,这不会产生太大的影响,而不是像矩阵等更大的数据结构。)
std::map<int,int> MyMap;
MyMap.emplace(5,10); // passing 5,10 to ctor of std::pair<const int,int> in-place
MyMap.insert(std::pair<const int,int>(5,10)); // construct a std::pair<const int,int> and pass it to insert, such that it creates a copy in the right location within the map
//similarly with the 'hint' methods
MyMap.emplace_hint(MyMap.end(),6,20);
MyMap.insert(MyMap.end(),std::pair<const int,int>(6,20));
顺便说一句,std::map<int,int>::value_type
实际上是std::pair<const int,int>
,而不是std::pair<int,int>
。
答案 3 :(得分:-2)
迭代器是一种设计模式,所有程序员都应该考虑到这一点。是的,迭代器并不是真的更快,但更清晰,它们允许您以安全和干净的方式“迭代”数据结构,因此您不必担心弄乱真实的信息。
在这种特殊情况下,你一次只插入一个值,因此迭代器实际上不是“最快”的解决方案,恰好是某些函数也可以使用它。
在第一个示例中,您在数据结构的“开始”处插入一个值,迭代器正在帮助您确定位置。
在第二个中,你只是在最后或默认的intersion位置插入值,所以你真的不需要迭代器。