c++ - unordered_set 范围插入 VS 迭代器

标签 c++ unordered-set

我试图理解为什么下面的范围插入比使用迭代器更快。

vector<string> &paths // 3 milion strings

方法一:范围插入

unordered_set<string> mySet;
mySet.insert(paths.begin(), paths.end());

方法二:迭代器

vector<string>::iterator row;
for (row = paths.begin(); row != paths.end(); row++)
{
  mySet.insert(row[0]);
}

结果:

方法 1:753 毫秒

方法 2:1221 毫秒

==============================

操作系统:Windows 10

IDE: Visual Studio Code

编译器:gcc 版本 8.1.0

标志:-O3

最佳答案

直觉上,范围插入过程应该更快。例如,假设您想插入一百万个元素。如果做范围插入,集合可以

  1. 计算总共要插入多少个元素,看看需要多少空间;
  2. 分配一个足够大的桶数组,以将负载因子保持在适当的范围内,可能会将所有旧元素移动到新表上;然后
  3. 插入所有元素。

还有一些可能的优化可以在这里完成(使用池分配器进行批量分配,执行多线程插入过程等),但我不确定这些是否真的完成了。

另一方面,如果一次插入一个东西,则每个步骤都需要执行一百万次。这意味着分配中间桶数组会浪费时间和空间,这些桶最终不会被使用,但实现无法告诉它们不会被使用,因为实现必须在每一步都保持良好状态。

对于 unordered_set,这些优化只是对每次插入的预期 O(1) 成本的改进。在其他一些容器中,例如 vectordeque,批量插入比重复的单个插入快得渐进,因为容器可以在批量插入期间移动其他元素一次,而不是做很多反复轮类。

希望这对您有所帮助!

关于c++ - unordered_set 范围插入 VS 迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59112605/

相关文章:

c++ - 函数定义在 cpp 文件中时出现链接器错误

c++调用非默认构造函数作为成员

c++ - 是否有任何关于为什么重新定义枚举器格式错误的规则?

c++ - 如何在 C++ 中只访问 unordered_set 的元素?

c++ - 实现 std::vector::push_back 强异常安全

c++ - 简化C++模式,其中包括变量名和函数输出

c++ - 来自 std 的 unordered_set

c++ - unordered_set 通过 lambdas 自定义哈希

如果使用自定义类类型作为键,C++ unordered_set 的计数和查找将不起作用

c++ - 来自 std::unordered_set<char> 的有效构造 std::string