vector 初始内存默认分配一个元素的内存长度,比如使用int声明的std::vector<int> vec,初始内存只存在四个字节,可以调用vec.reserve(1024)分配1024个节点的内存。vector使用之前不手动分配内存,使用效率会很慢,尤其使用自定义的类型对象涉及到拷贝析构,随意插入一个元素都会引起内存重新分配,元素重新拷贝。当然,系统也根据重新分配的次数进行分配优化,可以多分配空间。但是当元素足够多且使用自定义类型对象的时候,太影响效率。
vector内存分配代码 :
{ // push back a non-element
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
_Val);
++this->_Mylast;
每次自增长一个, 分配实现函数会优化计算分配当下元素个数的%50个,也就是当当下元素小于四个的时候, 每次自增长一个元素内存长度。元素达到四个时会分配两个。这样频繁分配,拷贝,构造很耗费效率。
以下是自己随便写的一段测试代码,测试结果:在默认声明的vector从尾部插入一千个元素时, 构造函数被调用1000次,拷贝赋值函数被调用三千多次,多出来的两千次为vector自增长时带来的副作用。耗时4313毫秒
代码中打开vec.reserve(1024);的注释后, 构造函数被调用1000次, 拷贝赋值函数调用1000次。 耗时1875ms。跟set插入耗时相当。
int g_struct = 0;
int flag[1000] = {0};
typedef struct rtu
{
int ID;
rtu()
{
std::cout<< "struct:"<<g_struct++<<std::endl;
ID= 0;
}
rtu(int num)
{
ID = num;
std::cout<< "struct"<<ID<<":----------"<<g_struct++<<std::endl;
}
bool operator == (const rtu& rt){
return this->ID == rt.ID;
}
rtu(const rtu& rt)
{
if (*this == rt)
{
return;
}
ID = rt.ID;
flag[ID]++;
std::cout<< "const"<<rt.ID<<"------"<<flag[ID]<<"----"<<g_num++ <<std::endl;
}
const rtu& operator = (const rtu& rt)
{
ID = rt.ID;
std::cout<< "operator"<<rt.ID<<":-------"<<g_num++ <<std::endl;
return *this;
}
{
return this->ID > rt2.ID;
}
}mrtu;
int _tmain(int argc, _TCHAR* argv[])
{
// NetProc* ptr = GetNetProcPst();
// ptr->BeginListen(L"192.168.0.74",8888,nullptr,nullptr);
// getchar();
// std::vector<rtu>* pst1;
// std::vector<rtu>* pst2;
// pst1 = &vec;
// int i = 0;
// while ( i++ < 100)
// {
// rtu rt;
// vec.push_back(rt);
// pst2 = (&vec);
// if((i == 1000) || (i == 100000))
// {
// if (pst1 != pst2)
// {
// std::cout<<"重新分配"<<i<<std::endl;
// }
// }
//
// }
//rtu temp[100];
std::vector<rtu> vec;
//mrtu temp(80);
//std::set<mrtu> vec(80);
//vec.reserve(1024);
int i = 0 ;
while (i++ < 1000)
{
rtu rt(i);
//rt.ID =( RAND_MAX * rand())%1000;
vec.push_back(rt);
}
return 0;
}
vector删除一个元素时,内存不会马上回收,只要vector没有失效,就算vector只剩下一个元素,vector占用的内存还是之前元素最多时候的值。比如vector原先存在一万个元素,删除9999个,但是占用的还是一万个的内存(这个在书上看到过,没有验证)
vector随机访问非常快,但随机插入效率非常慢,vector内部为了保证元素的连续性,往往插入一个元素后会引起大量的内存分配和内存拷贝。插入动作较多慎用。