C++ 为什么未初始化的 Vector 插入速度与push_back和赋值一样快?



为了理解矢量的行为,我编写了以下三个玩具示例:

  1. vector_using_assignment.cc:将向量初始化为1000000,并在for循环中分配其元素
// 1. vector_using_assignment
#include <iostream>
#include <vector>
int main(int argc, char *argv[]) {
int N = *argv[1];
std::vector<int> V(N);
for (int i =0; i < N; i++) {
V[i] = i;
}  
}
$ g++ -O0 -std=c++17 vector_using_assignment.cc -o vector_using_assignment
$ time ./vector_using_assignment 1000000
real    0m0.004s
user    0m0.003s
sys     0m0.001s
  1. vector_using_push_back.cc:创建一个空向量,然后使用push_back方法在for循环中分配其元素
// 2. vector_using_push_back.cc
#include <iostream>
#include <vector>
int main(int argc, char *argv[]) {
int N = *argv[1];
std::vector<int> V;
for (int i =0; i < N; i++) {
V.push_back(i);
}    
}
$ g++ -O0 -std=c++17 vector_using_push_back.cc -o vector_using_push_back
$ time ./vector_using_push_back 1000000
real    0m0.004s
user    0m0.004s
sys     0m0.000s
  1. vector_using_insert.cc创建一个空向量,然后使用insert方法在for循环中分配其元素
// 3. vector_using_insert.cc
#include <iostream>
#include <vector>
int main(int argc, char *argv[]) {
int N = *argv[1];
std::vector<int> V;
for (int i =0; i < N; i++) {
V.insert(V.begin(), N - i - 1);
}
}
$ g++ -O0 -std=c++17 vector_using_insert.cc -o vector_using_insert
$ time ./vector_using_insert 1000000
real  0m0.004s
user  0m0.003s
sys   0m0.001s

正如你所看到的,所有的方法都是完全相同的。我的理解是push_back在复杂性上是线性的(当大小<容量时(。在这个例子中显然不是这样。insert方法不应该也是线性的吗?

我的猜测是:

  1. c++17正在进行一些优化,即使我关闭了优化
  2. 我的机器有两个CPU,我想每个CPU有20个内核,还有32G RAM,所以这会让我的行为与我的想法不同吗?我尝试了100000000,但仍然没有看到任何变化

我做错了什么?

不出所料,在如何将stdin arg转换为int时出现了一个错误。正确的方法是:

int N = atoi(argv[1]);
std::cout << "N = " << N << std::endl;

现在我看到了一些真正的区别:

$ time ./vector_using_push_back 1000000000
N = 1000000000
real    0m20.139s
user    0m16.437s
sys 0m3.701s
$ time ./vector_using_assignment 1000000000
N = 1000000000
real    0m7.530s
user    0m6.005s
sys 0m1.525s
$ time ./vector_using_insert 1000000000
N = 1000000000
# I gave up after a couple of min

最新更新