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下为什么要选择以二倍的扩容机制。

相关推荐
代码雕刻家9 分钟前
课设实验-数据结构-单链表-文教文化用品品牌
c语言·开发语言·数据结构
sp_fyf_202425 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
rjszcb37 分钟前
一文说完c++全部基础知识,IO流(二)
c++
小字节,大梦想1 小时前
【C++】二叉搜索树
数据结构·c++
吾名招财1 小时前
yolov5-7.0模型DNN加载函数及参数详解(重要)
c++·人工智能·yolo·dnn
Pythonliu72 小时前
茴香豆 + Qwen-7B-Chat-Int8
linux·运维·服务器
你疯了抱抱我2 小时前
【RockyLinux 9.4】安装 NVIDIA 驱动,改变分辨率,避坑版本。(CentOS 系列也能用)
linux·运维·centos
我是哈哈hh2 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
憧憬成为原神糕手2 小时前
c++_ 多态
开发语言·c++
郭二哈2 小时前
C++——模板进阶、继承
java·服务器·c++