为了理解矢量的行为,我编写了以下三个玩具示例:
- 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
- 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
- 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
方法不应该也是线性的吗?
我的猜测是:
c++17
正在进行一些优化,即使我关闭了优化- 我的机器有两个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