c++的vector扩容机制
背景
vector里的内存已经满了后,在插入新的元素时就需要扩容,在 VS 下是 1.5倍,在 GCC 下是 2 倍。那么会产生两个问题:
(1)为什么是成倍增长,而不是每次增长一个固定大小的容量呢?
(2)为什么是以 2 倍或者 1.5 倍增长,而不是以 3 倍或者 4 倍等增长呢?
扩容机制
机制一
扩容以成倍方式增长:假设从1开始,扩容到100个大小,每次扩容2倍,vector的push_back的操作次数可以是logmN,也就是log2(100),换算下来大概是需要进行7次扩容,这样的话,数据需要拷贝7次。
扩容以倍数方式增长:假设需要扩容到100个,每次扩容10个值,则需要扩容10次,但是如果要扩容到1000个,扩容的次数就需要更多,如果需要扩容到5个,则倍数为10又太大了。
总结:以倍数方式增长的扩容方式扩容的次数比成倍方式更多,而且倍数的值也不好确定。
机制二
在 VS 下是1.5倍,在 GCC 下是2倍方式增长。
使用 k=2 增长因子的问题在于,每次扩展的新尺寸必然刚好大于之前分配的总和:
$$
c\sum_{i=1}^{n}2^i=c(2^{n+1}-1) < c2^{n+1}
$$
也就是说,之前分配的内存空间不可能被使用。这样对于缓存并不友好。最好把增长因子设为 1 < k < 2。
1 | k = 2,c = 4 |
总结:如上图所示,当 k =1.5 时,在几次扩展以后,可以重用之前的内存空间了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 胡椒粉的秋天!