vector扩容机制

在学习了vector的时候,总说linux下是以二倍扩容的,VS是以1.5倍扩容的。

但是想一想为什么扩容是这样的呢,为什么不能是3倍或者其他倍数呢? 所以带着这些疑问,接着往下看。

首先,我们要知道vector的扩容机制:当向vector插入元素的时候,即当_finish == _end_of_storage,可能就会触发扩容机制。

扩容有二种方式:

  • 等长个数扩容
  • 倍数扩容

等长个数扩容

等长个数扩容,新空间都是在原来的空间基础上增加K个空间。每当触发扩容的时候,就会将旧空间的数据移动到新空间去,同时将旧空间释放掉。

倍数扩容

假设向vector中插入n个元素,每当_finish== 2 ^k(0,1,2,3....)时,就会出现扩容。下面以VS和linux来观察看。

复制代码
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

VS下的测试结果:

linux下的测试结果:

可以看出,VS下的扩容差不多是以1.5倍来扩容的,而linux下的扩容是以2倍来扩容的。那么问题来了,为什么这样???

为什么都会选择倍数扩容

这是因为以等长个数来扩容的话,需要插入元素和移动元素操作总和是O(N),而以倍数扩容是O(1)。

而且VS和linux下都是以倍数扩容,还有一些原因是如果以等长个数扩容,那么个数应该是多少呢?如果太小的话,就可能导致频繁的扩容;如果太大的话,就可能出现一种情况,如果有100个元素,这是只需要再插入一个元素,但是需要扩容100个,这就导致了浪费了99个的空间。

为什么选择1.5倍或者2倍来扩容,而不是3倍或者其他倍数

最佳的扩容倍数

要想对空间的利用率最高,就是F(N-1) + F(N-2) >= F(N) ,时间上是F(N-1) + F(N-2) = F(N),这不就是1, 2 3 5 8....,所以最佳的扩容机制就是1.618

linux下为什么选择二倍扩容

我们都知道linux下都是通过页来管理内存的,通常是4KB,都是2的倍数。

这样做有三个好处:

  • 减少内存分配次数:以二倍的方式扩容可以减少内存分配的次数,每次扩容后,可以容纳更多的容量。
  • 提高性能:二倍的扩容机制可以更好的利用linux系统分配的机制,减少内存分配和释放的频率,提高性能。
  • 减少内存碎片:以二倍的方式扩容可以减少内存碎片,因为如果每次扩容都是增加一些小的容量,就有可能导致小的内存散布在堆上,增加了内存碎片的风险。

像linux下的伙伴系统就是以2的幂次方来分配内存和管理的一种算法,综合考虑,就理解了为什么linux下为什么要选择以二倍的扩容机制。

相关推荐
0 0 0几秒前
CCF-CSP第39次认证第三题——HTTP 头信息(HPACK)【C++】
开发语言·c++·算法
合方圆~小文5 分钟前
不同画面,三个镜头实时监控拍摄方案
数据结构·数据库·人工智能
Q8762239656 分钟前
西门子S7 - 1200控制5轴伺服程序与维纶触摸屏画面案例分享
数据结构
Data_agent12 分钟前
1688按图搜索1688商品(拍立淘)API ,Python请求示例
爬虫·python·算法·图搜索算法
汉克老师13 分钟前
2023年海淀区中小学信息学竞赛复赛(小学组试题第二题 回文时间 (time))
c++·算法·北京海淀中小学信息竞赛·模拟法
FED_AF16 分钟前
CUPS打印系统完全指南:从安装配置到故障排除
运维
代码雕刻家24 分钟前
1.9.课设实验-数据结构-图-校园跑最短路径
c语言·数据结构·算法·图论
white-persist38 分钟前
【攻防世界】reverse | re1-100 详细题解 WP
c语言·开发语言·网络·汇编·python·算法·网络安全
.YM.Z1 小时前
【数据结构】:排序(二)——归并与计数排序详解
数据结构·算法·排序