C++ push_back vs Insert vs emplace
C++ push_back vs Insert vs emplace
我目前正在用C++制作一个使用向量的应用程序。
我知道预优化是万恶之源。
但我真的忍不住好奇。
我正在将其他向量的一部分添加到另一个向量中
我们会说向量的大小永远不会改变300。
由于我总是将附加到矢量的末尾
这样做更快吗:a.reserve(300);
a.insert(a.end(), b.begin(), b.end());
或者循环通过我想要附加的向量并用CCD_ 3或CCD_。(不确定哪个更快)
有人能帮我吗?
这里有一个一般原则:当一个库同时提供do_x_once
和do_x_in_batch
时,后者应该至少与在简单循环中调用do_x_once
一样快。如果不是,那么库的实现就非常糟糕,因为一个简单的循环就足以获得更快的版本。通常,这样的批处理函数/方法可以执行额外的优化,因为它们了解数据结构内部。
因此,在循环中,insert
应该至少和push_back
一样快。在这种特殊情况下,insert
的智能实现可以为您想要插入的所有元素执行单个reserve
。push_back
每次都必须检查矢量的容量。不要试图智胜库:)
我想这实际上取决于编译器(库实现)、编译选项和体系结构。在没有优化(/Od)的情况下在英特尔至强的VS2005中进行快速基准测试:
std::vector<int> a;
std::vector<int> b;
// fill 'a' with random values for giggles
timer.start()
// copy values from 'a' to 'b'
timer.stop()
我使用这些不同的"复制值…"方法得到了10000个项目的结果:
- 为"b"保留空间,然后使用
b.push_back(a[i]);
为循环保留空间:0.808秒 - 调整"b"的大小,然后对于使用索引分配的循环
b[i] = a[i];
:0.264秒 - 没有重新调整"b"的大小,只有
b.insert(b.end(), a.begin(), a.end());
:0.021秒(与保留先无显著差异) std::copy(a.begin(), a.end(), std::back_inserter(b));
:0.944秒(0.871,先保留)- 调整"b"的大小,然后在基指针
memcpy(&(b[0]), &(a[0]), 10000000*sizeof(int));
:0.061秒上进行memcopy
然而,启用了优化(/Ox),情况就不同了。我不得不将尺寸增加到100000 000以获得更多差异化:
- push_back循环:0.659秒
- 索引循环:0.482秒
- 插入时间:0.210秒(与先保留时间无显著差异)
- std::复制:0.422秒,先保留。没有它就有一个坏家伙
- 记忆时间:0.329秒
值得注意的是,无论是否进行优化,insert方法都是线性缩放的。其他方法在没有优化的情况下显然效率低下,但使用它们仍然无法达到很快的速度。正如詹姆斯·坎泽所指出的,g++上的情况有所不同。使用您自己的平台运行测试以进行验证。
正如larsmans所说,在单个库调用中执行的操作越多它更有可能更有效率。在insert
的情况下到一个向量中,库通常最多只做一个重新分配以及最多复制一次每个移位的元素。如果使用循环和push_back
,它可以重新分配几个时间,可能会慢得多(比如幅度)。
然而,根据类型的不同,它也可能更快类似于:
a.resize( 300 );
std::copy( b.begin(), b.end(), a.end() - 300 );
我发现对于简单的标量类型(比如int
)在英特尔机器上使用g++。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- Insert函数不适用于2 if语句C++
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 如何在C++向量中奇数元素前面加上值-1,我在使用insert函数时遇到了问题
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 完美前进使用 std::forward vs RefRefCast
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- consteval wrapper vs. source_location
- C++ push_back vs Insert vs emplace