毕竟,他们做同样的事情。不是吗?
没有。它们不一样。与std::vector::insert 相比,使用std::vector::push_back 的第一种方法将经历多次重新分配。
insert 将在复制范围之前根据当前的std::vector::capacity 在内部分配内存。有关更多信息,请参阅以下讨论:
Does std::vector::insert reserve by definition?
但是性能上有什么区别吗?
由于上述原因,第二种方法会显示出轻微的性能提升。例如,请参阅下面的快速基准,使用 http://quick-bench.com:
See online bench-mark
或者编写一个测试程序来测量性能(如@Some程序员老兄在cmets中提到的)。以下是一个示例测试程序:
#include <iostream>
#include <chrono>
#include <algorithm>
#include <vector>
using namespace std::chrono;
class Timer final
{
private:
time_point<high_resolution_clock> _startTime;
public:
Timer() noexcept
: _startTime{ high_resolution_clock::now() }
{}
~Timer() noexcept { Stop(); }
void Stop() noexcept
{
const auto endTime = high_resolution_clock::now();
const auto start = time_point_cast<microseconds>(_startTime).time_since_epoch();
const auto end = time_point_cast<microseconds>(endTime).time_since_epoch();
const auto durationTaken = end - start;
const auto duration_ms = durationTaken * 0.001;
std::cout << durationTaken.count() << "us (" << duration_ms.count() << "ms)\n";
}
};
// Method 1: push_back
void push_back()
{
std::cout << "push_backing: ";
Timer time{};
for (auto i{ 0ULL }; i < 1000'000; ++i)
{
std::vector<int> vec = { 1 };
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
}
}
// Method 2: insert_range
void insert_range()
{
std::cout << "range-inserting: ";
Timer time{};
for (auto i{ 0ULL }; i < 1000'000; ++i)
{
std::vector<int> vec = { 1 };
int arr[] = { 2,3,4,5 };
vec.insert(std::end(vec), std::cbegin(arr), std::cend(arr));
}
}
int main()
{
push_back();
insert_range();
return 0;
}
使用我的系统发布构建(MSVS2019:/Ox /std:c++17,AMD Ryzen 7 2700x(8 核,3.70 Ghz) , x64 Windows 10)
// Build - 1
push_backing: 285199us (285.199ms)
range-inserting: 103388us (103.388ms)
// Build - 2
push_backing: 280378us (280.378ms)
range-inserting: 104032us (104.032ms)
// Build - 3
push_backing: 281818us (281.818ms)
range-inserting: 102803us (102.803ms)
对于给定的场景,std::vector::insert ing 比 std::vector::push_back 快大约 2.7 倍。
根据实现,看看其他编译器(clang 8.0 和 gcc 9.2)想说什么:https://godbolt.org/z/DQrq51