写了一段代码发现和我预期不一致,搜了一下也没搜到原因,于是就对比了一下SGI STL和VS使用的STL的vector容量增长情况,看了下vs的代码,觉得这还是需要注意下的。如果vs不是自己配的SGISTL的话可能就出现有些和预期不一致的地方
vector我一开一直以为内存消耗都是按照倍增增长的,结果输出真的吃了一惊:
#include <iostream>
#include <vector>
using namespace std;
class A{
public:
A(){ /*cout << "A constructor" << endl;*/ }
A(const A& a){/* cout << "A copy con" << endl;*/ }
~A(){/* cout << "A destr" << endl;*/ }
};
int main(){
vector<A> vec;
for (int i = 0; i < 10; ++i)
{
cout << "vec.capacity():" << vec.capacity() << endl;
vec.push_back(A());
cout << "----------------" << endl;
}
cout << "vec.size():" << vec.size() << endl;
cout << "vec.capacity():" << vec.capacity()<< endl;
cout << "vec.max_size():"<<vec.max_size() << endl;
return 0;
}
本来在这个class的定义是写在main函数里面的,结果在linux下gcc编译不过,不允许vector内存储局部类型所以就提到外面来了。
这段代码在vs下结果如下:
在gcc(SGI STL)下
在sgiSTL下和我们预期是一致的,那个vs是如何处理的呢:
size_type _Grow_to(size_type _Count) const
{ // grow by 50% or at least to _Count
size_type _Capacity = capacity();
_Capacity = max_size() - _Capacity / 2 < _Capacity
? 0 : _Capacity + _Capacity / 2; // try to grow by 50%
if (_Capacity < _Count)
_Capacity = _Count;
return (_Capacity);
}
原来VS下vector的内存增长策略都是 在不足时以50%扩增
这种问题一直以为没必要测呢,倍增一直奉为真理一般,结果发现自己差点就要错好长时间了
注:不同的内存增长策略的影响对程序有哪些影响即这个论题的意义:
假设初始容量为0,M为vector的size:
在倍增情况下,内存申请次数为log(2)(M)+1;拷贝构造次数约为M ;
在半增情况下,内存申请次数约为(lgM - lg2)/lg(3/2);拷贝次数约为2M;
在此种情况下最优处理:vec.reserve(enough large) vec.swap(vec1(vec)):
内存申请次数2,copy次数M,内存消耗M
当然如果确切知道vec需要存储多少东西 vec.reserve(size)
内存申请1次,copy 0次
(这里所说的cpy均指内存变换时的cpy)