[小白拿捏面试题]第一篇:往vector里边插入10万个数字,怎么提高效率

目录

三种方法讲解阿里巴巴面试题

方法一:在插入数据之前,提前分配内存,把空间开好

方法二:使用构造函数初始化

方法三:使用emplace_back()

鸡汤


三种方法讲解阿里巴巴面试题

在学习这个题目之前推荐小伙伴们先去看一下我的STL专栏,学习一下vector基本使用以及原理

面试题:在C++中,往vector中插入10万个数字,怎么做能保证性能较高?

我看到这个题目脑子里出现的第一个想法:首先就是想提前配置好空间,因为vector是动态分配空间存储数据,提前配置好空间就可以不用中途重新分配 ,接下来让我们一起看看有哪些方法可以提高性能吧,我们一起冲鸭!

方法一:在插入数据之前,提前分配内存,把空间开好

写代码测试一下,我用的是Visual Studio编写代码的;

先计算没有优化前花费的时间代码如下:

#include <iostream> //C++标准头文件
#include <vector>   
#include <chrono>

using namespace std;

//这里就正常插入数据不做优化
int main()
{
	//记录程序开始运行时的时间
	auto begin_time = chrono::high_resolution_clock::now();
	vector<int> v;
	for (int i = 0; i < 100000; ++i)
	{
		//为了验证方便,我们把i当做数据直接插入
		v.push_back(i); 
	}
	//记录程序运行结束时的时间
	auto finsh_time = chrono::high_resolution_clock::now();

	//计算并输出花费的时间
	auto timetaken = chrono::duration_cast<chrono::microseconds>(finsh_time - begin_time);
	cout << "花费的时间: " << timetaken.count() << endl;

}

 输出    花费时间: 46336

 接下来是利用预先分配内存做优化,代码如下:

//这里利用提前分配内存进行优化
int main()
{
	//记录程序开始运行时的时间
	auto begin_time = chrono::high_resolution_clock::now();
	vector<int> v;
	//提前开空间
	v.reserve(100000);
	for (int i = 0; i < 100000; ++i)
	{
		//为了验证方便,我们把i当做数据直接插入
		v.push_back(i);
	}
	//记录程序运行结束时的时间
	auto finsh_time = chrono::high_resolution_clock::now();
	//计算并输出花费的时间
	auto timetaken = chrono::duration_cast<chrono::microseconds>(finsh_time - begin_time);
	cout << "花费的时间: " << timetaken.count() << endl;

}

 输出        花费的时间40563

 从46336 -------------------->40563

 可以看出来有效率的提升但是不明显!那么想一下还有哪里可以优化的?或者说哪些操作占用我们这么长的时间?不要急,我们继续向下看.

方法二:使用构造函数初始化

在想一下哪些操作占用我们这么久的时间呢?小伙伴们已经猜到了,没错就是进行了10万次的push_back()尾部插入操作耗费我们的时间?那么怎么解决?是的哇,利用我们vector的构造函数直接开好空间并且赋予初始值.

接下来看代码:

#include <iostream> //C++标准头文件
#include <vector>   
#include <chrono>

using namespace std;

int main()
{
	//记录程序开始运行时的时间
	auto begin_time = chrono::high_resolution_clock::now();
	vector<int> v(100000);
	for (int i = 0; i < 100000; ++i)
	{
		v[i] = i;//一定注意这里的细节,直接用下标进行赋值
	}
	//记录程序运行结束时的时间
	auto finsh_time = chrono::high_resolution_clock::now();
	//计算并输出花费的时间
	auto timetaken = chrono::duration_cast<chrono::microseconds>(finsh_time - begin_time);
	cout << "花费的时间: " << timetaken.count() << endl;
	return 0;
}

 输出        花费的时间: 2624

我们的花费时间从 从46336 -------------------->40563-------------------->2624

哇塞这下震惊了,效率直接提升了一个数量级,从5位数直接变成4位数;

那么不废话,得到原因:使用下标赋值本质是一个直接的内存访问操作,直接对地址进行操作,通常是一个O(1)常数的时间操作.

方法三:使用emplace_back()

(这里讲的知识移动构造不要着急后边会讲解):emplace_back() 直接在向量尾部构造对象,避免了对象的拷贝或移动。这对于内置类型(如 int)并没有显著优势,但对于自定义类型或复杂类型可能会提高性能。

直接看代码:

#include <iostream> //C++标准头文件
#include <vector>   
#include <chrono>

using namespace std;


int main()
{
	//记录程序开始运行时的时间
	auto begin_time = chrono::high_resolution_clock::now();
	std::vector<int> vec; 
	vec.reserve(100000);
	//填充向量    
	for (int i = 0; i < 100000; ++i)
	{
		vec.emplace_back(i);
	}
	//记录程序运行结束时的时间
	auto finsh_time = chrono::high_resolution_clock::now();
	//计算并输出花费的时间
	auto timetaken = chrono::duration_cast<chrono::microseconds>(finsh_time - begin_time);
	cout << "花费的时间: " << timetaken.count() << endl;
	return 0;
}

 输出        花费的时间: 38592

 对比使用push_back()有点提升,但是不多,针对int这样的内置类型没有体现出来优势,但是针对自定义类型或者复杂类型可能会提高性能.

三种方法对比下来,使用方案二效率最高

总结:
针对这道题目来说,采用先初始化,然后使用下标赋值是性能最高的方法.

鸡汤

一遍不会没关系吖,多看几遍,我也是学了好多遍呢,小伙伴们肯定学的又快又好!!!最后希望写的内容对小伙伴们有所帮助,我写的如果有哪里不对的地方请指出来哦!让我们一起进步吖,任何疑问包括心情不好都可以找我聊聊,我很乐意当你的倾听者吖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫珂蛋儿吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值