模拟实际生产情况的测试代码,map中的value保存的是对象。
#include<map>
#include<vector>
#include<string>
#include <iostream>
#include <time.h>
using namespace std;
class useTest
{
public:
useTest() {};
map<string,string> testMap;
vector<string> testVertor;
string id;
};
void clearData(map<int, useTest>& needClearMap)
{
clock_t startt = clock();
//分别通过去注释测试下面四种情况
//使用clear
needClearMap.clear();
//使用swap
//map<int, useTest> uu;
//needClearMap.swap(uu);
//使用erase
//needClearMap.erase(needClearMap.begin(), needClearMap.end());
//使用for erase
//for (auto iter = needClearMap.begin(); iter != needClearMap.end(); iter = needClearMap.erase(iter)) {}
double sec = double(clock() - startt) / CLOCKS_PER_SEC;
std::cout << "In Clear Cost Time:" << sec << endl;
}
void test()
{
map<int, useTest> needClearMap;
for (size_t i = 0; i <= 10000; ++i)
{
useTest uT;
for (size_t ii = 0; ii <= 1000; ++ii)
{
uT.testMap[to_string(ii)] = "我是测试,我是测试,我就是测试string";
uT.testVertor.push_back("我也是测试,我也是测试,我就是测试string");
}
uT.id = to_string(i);
//cout << i << endl;
needClearMap[i] = uT;
}
clock_t startt = clock();
clearData(needClearMap);
double sec = double(clock() - startt) / CLOCKS_PER_SEC;
std::cout << "clearData Cost Time:" << sec << endl;
}
int main()
{
for (size_t i = 0; i < 10; ++i)
{
test();
}
getchar();
}
测试结论
就单单实现某个map清空来说,swap效率最高,几乎是0耗时。但是当退出整个函数,释放swap转移到的临时对象要耗一定的时间。
erase效率稍微比clear高。通过for循环erase好似效率又高点。
内存释放:
STL容器调用clear()方法,通常只是使得容器内部的对象通通析构,但容器本身的内存无法得到释放。即篮子里面东西拿走了,篮子占的空间还在,这样是为了方便下次存放新的对象时,不需要再次申请空间。
其他同学的blog中有很多例子,即clear()后,容器的size为0,但capacity不变,
- 通过swap()空容器,来彻底释放容器占用的capacity.
对于map,set,unordered_map等容器,调用clear(), swap()都无法使得内存真正释放。虽然很多地方谈到,这一现象(内存被保留下来)是正常的,并不需要担心。但是当大量使用堆内存存放不同的数据结构,会造成严重的内存碎片从而导致内存泄漏问题。
解决方法
只需添加一行,malloc_trim(0); 这一行代码会将空闲的堆内存归还给操作系统,供其他进程使用。
#include <iostream>
#include <map>
#include <malloc.h>
using namespace std;
void func()
{
map<int,string> mp;
int i = 5000000;
while(i--)
mp.insert(make_pair(i,string("hell000o")));
map<int,string>().swap(mp);
}
int main()
{
func();
cout <<"done."<<endl;
malloc_trim(0);
while(1);
}