C++学习笔记:vector的机制与使用优化【Cherno】

首先说一句:vector不优化的话实在是太~~慢了;

vector的工作机制很简单,当我们向vector中push一个元素,且vector中的容量不够时,vector就会寻找另一块能够容纳新加入元素后的内存块【有的编译器是新内存块相对旧内存块的大小指数增长,有的是线性增长,本菜的编译器是线性增长】,然后旧内存块和新元素按照顺序copy新内存块中:

如下:

#include<iostream>
#include<vector>
using namespace std;

class test {
	int x;
public:

	test() {}

	test(int scr):x(scr) {
		//cout << "Create" << endl;
	}

	test(const test& scr) {
		memcpy(this, &scr, sizeof(scr));
		cout << "copy" << endl;
	}

	~test() {
		//cout << "Destroyed" << endl;
	}
};

int main() {

	vector<test> st;
	test A, B, C;

	st.push_back(A);
	st.push_back(B);
	st.push_back(C);

	cout << st.size() << endl;
	cin.get();
}

运行结果:

 因为是线性增长的,所以新内存相对旧内存只多了一个位置,所以copy了1+2+3次;

这无疑会消耗很多时间,所以我们就可以使用vector的reserve函数了优化这个过程了,与这个函数对标的是resize函数,下面来介绍着两种函数是怎么工作的,然后在知道了工作原理的基础上来讲怎么优化;

reserve:

这个函数和其名字一样,是在vector容器中预留一些位置,但是这些位置不是元素实例,而是单单地开放对等的空间而已;

比如我们有以下代码:

#include<iostream>
#include<vector>
using namespace std;

int main() {

	vector<int> test;

	test.reserve(10);

	test[1] = 1;
}

程序会报错:

 因为并不存在实例化的int型,它只是预留了与10个int型对等的空间大小;

然后是resize函数了;

这个函数就会在开辟空间的同时进行实例化:

还是上面的代码:

#include<iostream>
#include<vector>
using namespace std;

int main() {

	vector<int> test;

	test.resize(10);

	test[1] = 1;
}

程序可以正常运行:

因为resize实例化了int型;

然后如何优化呢?这里主要围绕reserve来展开:

对比刚开始的那串代码,如何我们我先预留出一些空间,如何再push_back的话,那么就有如下场景:

#include<iostream>
#include<vector>
using namespace std;

class test {
	int x;
public:

	test() {}

	test(int scr) :x(scr) {
		cout << "Create" << endl;
	}

	test(const test& scr) {
		memcpy(this, &scr, sizeof(scr));
		cout << "copy" << endl;
	}

	~test() {
		cout << "Destroyed" << endl;
	}
};

int main() {

	vector<test> st;

	st.reserve(10);

	st.push_back(1);
	st.push_back(2);
	st.push_back(3);

	cout << st.size() << endl;
	cin.get();
}

运行结果:

嗯~相对第一次的6次copy,效率高了一倍呢;

那为什么会这样呢?

很简单,程序先用push_back里的值实例化了一个无名变量【Create】,如何讲这个无名变量的copy到预留空间中了【Copy】,如果因为无名变量没有用,所以就将无名变量释放掉了【Destroyed】,然后这个工作持续了3次;

那我们能不能进一步优化呢?

当然可以,我们可以利用emplace_back这个函数;

这个函数如果在vector容器的预留空间不够的情况下,是和push_back函数相同的,即先实例化一个无名变量,然后开新内存copy旧内存,但是在有预留空间的情况下,emplace的效率就要高很多,看下面代码:

#include<iostream>
#include<vector>
using namespace std;

class test {
	int x;
public:

	test() {}

	test(int scr) :x(scr) {
		cout << "Create" << endl;
	}

	test(const test& scr) {
		memcpy(this, &scr, sizeof(scr));
		cout << "copy" << endl;
	}

	~test() {
		cout << "Destroyed" << endl;
	}
};

int main() {

	vector<test> st;
	st.reserve(10);
	st.emplace_back(1);
	st.emplace_back(2);
	st.emplace_back(3);
	st.emplace_back(4);

	cout << st.size() << endl;
	cin.get();
}

运行结果:

 由此可知,emplace是直接对预留空间操作,即直接在预留空间在实例化对象,所以我们可以少去很多Destroy和Copy的时间开销,由此达到优化的目的;

好了,基本的就这些了,以后会继续更新容器的优化;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值