C++中vector容器为什么扩容时按照2倍或者1.5倍进行扩容
扩容机制首先在VS2013底下,vector的扩容操作是每次扩容*1.5;在GCC环境下是2倍。GCC下的扩容方式是以二倍形式扩容。VS2013下是以1.5倍进行扩容所以可能会有疑问:问题一:为什么非要以倍数的形式增长,而不是以个数的形式增长。问题二:为什么每次增长是1.5倍或者2倍形式,而不是3倍或者4倍形式增长。详解问题一倍数方式空间拷贝数据次数假设总共有n个元素,以m倍的形式增长。(比如现在
扩容机制
首先在VS2013底下,vector的扩容操作是每次扩容*1.5;在GCC环境下是2倍。
- GCC下的扩容方式是以二倍形式扩容。
- VS2013下是以1.5倍进行扩容
所以可能会有疑问: - 问题一:为什么非要以倍数的形式增长,而不是以个数的形式增长。
- 问题二:为什么每次增长是1.5倍或者2倍形式,而不是3倍或者4倍形式增长。
假设总共有n个元素,以m倍的形式增长。(比如现在举例n=100, m=2),所以,vector的push_back的操作次数可以是logmN,也就是log2(100),换算下来大概是需要进行7次扩容。这样的话,相当于旧空间数据到原空间数据的拷贝有7次。
和倍数方式假设相同,n=100;这次m代表的是每次新空间的大小位n+m;m为新空间新增大小,比如这次m为10(每次新增10个空间)。所以这次的扩容次数为 100/10 = 10次,也就是说,插入100白个元素,需要扩容10次。
但是,如果n=1000的情况下, 以个数形式进行扩容就不能在为10了,否则拷贝空间次数将会太多
有的小伙伴要问:但是可以取100呀,想想,如果n=10的情况下,取100又不太合适,所以,以个数的形式来进行扩容显然不符合所用n的取值。
所以在STL中vector以倍数的形式进行扩容
如果以大于2倍的方式来进行扩容,下一次申请空间会大于之前申请所有空间的总和,这样会导致之前的空间不能再被重复利用,这样是很浪费空间的操作。所以,如果扩容一般基于(1, 2] 之间进行扩容
- 当m=2时
因为每次扩容都满足等比数列通项公式an = a1*q^(n-1) = 4*2^(n-1)
而前n-1项的内存和为Sn = a1*(1-q^(n-1))/(1-q) = 4*2^(n-1)-4
所以第n项和前n-1和之间的差值为an - Sn = 4
,这也就说明,前n-1项不能够完成第n项的空间重用。 - 当m= 1.5时
同样的方法,计算出an - Sn = 8 - 4*1.5^(n-1)
所以,当n达到一定的值的时候,就可以利用内存分配的方式将之前的空间进行重用,所以一般情况下为了使其为整数,选用2倍或者1.5倍来进行扩容。
更多推荐
所有评论(0)