vector使用优化

vector使用优化

vector是C++中的动态数组,它的容量capacity随着元素的增加,可以动态长。而容量每一次生长时候,意味着重新开辟一块内存,将原有的数据拷贝到新的内存上,并删除之前的数据。

基于这个特点,可以对vector的使用进行适当的优化。

野蛮复制

下面一段代码,执行目的是要在std::vector<Student> vecs中插入三个同学对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector>

class Student {
public:
Student(std::string name, int age) {
name_ = name;
age_ = age;
printf("construct \n");
}
Student(const Student& stu)
: name_(stu.name_), age_(stu.age_)
{
printf("copy \n");
}
private:
std::string name_;
int age_;
};

int main() {
std::vector<Student> vecs;
vecs.push_back(Student("小刚", 10));
printf("======================== \n");
vecs.push_back(Student("小红", 11));
printf("======================== \n");
vecs.push_back(Student("小李", 12));
std::cin.get();
}

打印结果

1
2
3
4
5
6
7
8
9
10
11
construct
copy
========================
construct
copy
copy
========================
construct
copy
copy
copy

可以看到向vecs添加三个元素,Student的构造函数执行了3次,构造复制了6次,如果插入的学生更多,这个复制次数会野蛮生长。

reserve设置容量

根据使用场景,reserve提前分设置容量,这样可以避免每一次capacity自生长带来的内存分配和copy动作。

1
2
3
4
5
6
7
8
9
10
int main() {
std::vector<Student> vecs;
vecs.reserve(3);
vecs.push_back(Student("小刚", 10));
printf("======================== \n");
vecs.push_back(Student("小红", 11));
printf("======================== \n");
vecs.push_back(Student("小李", 12));
std::cin.get();
}

打印结果

1
2
3
4
5
6
7
8
construct
copy
========================
construct
copy
========================
construct
copy

emplace_back

push_back入参是容器元素类型本身,每次添加元素会构造临时的对象,而实际添加到容器中的又是拷贝出来的那个对象。C++提供了emplace_back接口,通过构造入参直接再容器中构造对象。

1
2
3
4
5
6
7
8
9
10
int main() {
std::vector<Student> vecs;
vecs.reserve(3);
vecs.emplace_back("小刚", 10);
printf("======================== \n");
vecs.emplace_back("小红", 11);
printf("======================== \n");
vecs.emplace_back("小李", 12);
std::cin.get();
}

打印结果

1
2
3
4
5
construct
========================
construct
========================
construct

现在看打印结果,已经没有copy字样了,代码变得更加高效,三次代码达到了同样的目的,但是经过几次优化后,代码执行过程中不再有冗余的副本产生。



关注博客或微信搜索公众号多媒体与图形,获取更多内容,欢迎在公众号留言交流!
扫一扫关注公众号
作者

占航

发布于

2022-07-24

更新于

2023-10-04

许可协议

评论