Vector的优化使用 in C++【C++学习笔记】

48Vector的优化使用 in C++

vector能来回变化容量的原理是:新增一个元素,而数组容量不能容纳新元素,那么它就会开辟新的更大的内存块,把原有的和新增的元素全复制过去,然后把旧的内存块删除

这种调整大小,重新分配的操作是很费时的(复制所以元素+重新分配),而这是要避免的,而这便是优化的方向,对于复制的优化策略。

我们如何避免复制对象呢?特别是基于vector的对象(没有储存vecotr指针,而是对象)

🍅寻找策略

#include <iostream>
#include <vector>
using std::cout;
using std::endl;
class Entity {
public:
    int x, y, z;
    Entity() {}
    Entity(const Entity &other) {
        cout << "复制" << endl;
    }
};
int main()
{
    std::vector<Entity>vec;//1次
    vec.push_back(Entity());
    //程序结果是:输出了 一 个 “复制”
    return 0;
}

出现这个的原因是:当我们在创建Entity时,我们在main的栈上创建了它,然后从main函数复制到了实际的vector

  • 这就引出第一个策略:如果能直接把Entity建立在vector分配的内存中,就可以省略复制这一步操作
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
class Entity {
public:
    int x, y, z;
    Entity() {}
    Entity(const Entity &other) {
        cout << "复制" << endl;
    }
};
int main()
{
    std::vector<Entity>vec;
    vec.push_back(Entity());//1次
    vec.push_back(Entity());//2次
    //程序结果是:输出了 三 个 “复制”
    return 0;
}

三个复制,有两个复制是因为上面的原因:两次从主函数复制到vector中,而还有一次复制是因为第一次的vector容量是1,装不下两个元素,所以它需要扩容成容量2,然后把原数组的第一个元素复制过去,然后再把新的第二个元素装进去,这就是第三个复制。

#include <iostream>
#include <vector>
using std::cout;
using std::endl;
class Entity {
public:
    int x, y, z;
    Entity() {}
    Entity(const Entity &other) {
        cout << "复制" << endl;
    }
};
int main()
{
    std::vector<Entity>vec;
    vec.push_back(Entity());//1
    vec.push_back(Entity());//2
    vec.push_back(Entity());//3
    //会输出 六 个 “复制”
    return 0;
}

同理,要从主函数复制到vector三次,然后两次扩容,第一次扩容时把原vector里的一个元素复制新vector里,第二次扩容时把原vector里的两个元素复制新vector里,所以又有三次复制

  • 所以这类有第二个优化策略:可以直接告诉vector指定容量就是3,这样子就不需要扩容了

🍅优化手段

💡💡💡设置vector容量:[vector名字].reserve([容量]),解决反复扩容问题

  • std::vector<Entity> vec;
    vec.reserve(3);	//把vector的容量设置为3
    

    这个与下面这个是有区别的

    std::vector<Entity> vec(3);
    //这个是直接在定义vector的时候就设置3
    

    这里设置的结果不是把容量扩容成3,它实际上会构造三个Entity对象,即是一开始就是满的,不是空的!!!!

    但最初的想法只是有足够的内存来容纳它们,而不是一上来就创建三个对象把它们填满

    reserve函数的功能就是单纯创建足够的内存,其余多余的什么也不干

    (如果不用reserve的话,复制的操作数会以指数级别增长!)

💡💡💡用emplace_back代替push_back,解决反复复制问题

如果用push_back,那么进行的操作是从主函数复制对象到vector中

而如果用emplace_back,则是直接在实际的vector中构造

vec.push_back(Entity(1, 2, 3));
//push_back需要传递我们已经构建的Entity对象
vec.emplace_back(1, 2, 3);
//emplace_back则不需要传递已构建的Entity对象,只需要传递了构造函数的参数列表
//相当于告诉vector:在我们实际的vector内存中,使用以下参数(参数列表),构造一个Entity对象(直接在vector里)

如果完成了上面两种优化策略,则不会出现一个复制操作,而这只是简单的优化策略,但是可以比最初的代码快一个阶级

这里的内容实在是太有用了!!!!!!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值