basic
#include <iostream>
#include <vector>
struct Vertex {
float x, y, z;
Vertex(float x, float y, float z) : x(x), y(y), z(z) {}
};
std::ostream& operator<<(std::ostream& ostream, const Vertex& vertex){
ostream << vertex.x << ", " << vertex.y << ", " << vertex.z;
return ostream;
}
int main() {
std::vector<Vertex> vertices;
vertices.push_back({1,2,3});
vertices.emplace_back(11,22,33);
vertices.erase(vertices.begin()+1);
for (const Vertex& v : vertices) {
std::cout << v << std::endl;
}
std::cin.get();
optimization
e.g. 加入copy constructor:
struct Vertex {
float x, y, z;
Vertex(float x, float y, float z) : x(x), y(y), z(z) {}
Vertex(const Vertex& vertex) : x(vertex.x), y(vertex.y), z(vertex.z) {
std::cout << "Copied!" << std::endl;
}
};
std::ostream& operator<<(std::ostream& ostream, const Vertex& vertex){
ostream << vertex.x << ", " << vertex.y << ", " << vertex.z;
return ostream;
}
int main() {
std::vector<Vertex> vertices;
vertices.push_back(Vertex(1,2,3));
vertices.push_back(Vertex(4,5,6));
vertices.push_back(Vertex(7,8,9));
for (const Vertex& v : vertices) {
std::cout << v << std::endl;
}
std::cin.get();
}
Output:
Copied!
Copied!
Copied!
Copied!
Copied!
Copied!
1, 2, 3
4, 5, 6
7, 8, 9
6次std::cout << "Copied!" << std::endl;
: 极其低效:这是因为vector类似arrayList, 逐个添加Vertex对象会出现“在main主stack上加入一个Vertex对象,然后copy整个扩容之后能容纳多一个element的vector到新的memory”这个过程; i.e.
debug到push_back(Vertex(4,5,6))
这里,此时vertices.size
是2, 之前是1的:这是因为一开始没设置大小,就只能放一个Vertex(1,2,3)
对象;现在又要放一个Vertex(4,5,6)
, 就会有下面两步:
1.Vertex(4,5,6)
:在main函数中创建这个对象,copy到vertices,一次copy
- 之前内含
Vertex(1,2,3)
的vertices,因为要多容纳一个element,所以增大一位后自身copy到另外的memory,因为内部本身有一个元素,所以又一次copy: 共2次;
所以push_back(Vertex(7,8,9))
的时候好理解:自身main到vertices一次,vertices本身2个元素扩容增大1转移的2次copy,一共3次;其实改写一下copy constructor就看的非常清楚:
整个copy的stack看的都很清楚; 注意⚠️这个增加速度是n(n+1)/2
, 所以增加的很快
解决1: 指定vertices所需memory大小:reserve
reserve
给vertices分配memory,让vertices开始capacity设置为能容纳3个Vertex对象,就不用每次push_back都扩容了;
注意并不是vertices(3)
:
i.e. 创建vertices的时候并不创建任何Vertex对象,vertices(3)
是创建vertices的时候就创建了3个Vertex对象:只是需要vertices有3个Vertex对象的大小而已。
解决2: 直接in-place在vertices中创建Vertex对象
上述还是有3次copy:是在main函数创建Vertex对象然后从此stack copy到vertices的过程:如果能直接在vertices创建对象那么这三次copy也能省去: emplace_back
int main() {
std::vector<Vertex> vertices;
vertices.emplace_back(1,2,3);
vertices.emplace_back(4,5,6);
vertices.emplace_back(7,8,9);
for (const Vertex& v : vertices) {
std::cout << v << std::endl;
}
std::cin.get();
}
就完全不调用copy constructor了,一次copy都没有
Skipped 48-52:
- Making & working w. Libraries (multiple projects)
- Deal with multiple returning values