文章目录
1. 现实问题
生产中接收历史股票行情做一些别的计算时。整个计算系统的大概流程如下:
因为json解析比较耗时,所以采用了分割vector后多线程解析json成Json::Value对象数据,并通过日期时间作为key插入保存在同一个map中,这样解析后的数据也是按key 日期时间有序。从而保存后续的计算没有问题。
遇到的问题是,当map的value保存的是对象且map很大时,clear释放的时候比较耗时。63W条数据,要26秒,太慢了。影响了整个系统的效率。
2. 测试环境
2.1 计算机情况
2.2 IDE运行情况
使用VS2019社区版,编译x64.Release版本直接在vs下运行。项目属性,优化选项采用默认的,最大优化。
3. 测试代码
模拟实际生产情况的测试代码,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();
}
4. 测试结果
for循环10次测试情况
4.1 使用clear
In Clear Cost Time:2.141
clearData Cost Time:2.142
In Clear Cost Time:2.522
clearData Cost Time:2.523
In Clear Cost Time:2.633
clearData Cost Time:2.633
In Clear Cost Time:2.834
clearData Cost Time:2.836
In Clear Cost Time:2.748
clearData Cost Time:2.749
In Clear Cost Time:2.919
clearData Cost Time:2.919
In Clear Cost Time:4.114
clearData Cost Time:4.116
In Clear Cost Time:3.734
clearData Cost Time:3.735
In Clear Cost Time:4.147
clearData Cost Time:4.147
In Clear Cost Time:3.949
clearData Cost Time:3.949
4.2 使用swap
In Clear Cost Time:0
clearData Cost Time:1.962
In Clear Cost Time:0
clearData Cost Time:2.102
In Clear Cost Time:0
clearData Cost Time:2.22
In Clear Cost Time:0
clearData Cost Time:2.258
In Clear Cost Time:0
clearData Cost Time:2.457
In Clear Cost Time:0
clearData Cost Time:2.908
In Clear Cost Time:0
clearData Cost Time:3.358
In Clear Cost Time:0
clearData Cost Time:3.352
In Clear Cost Time:0
clearData Cost Time:3.236
In Clear Cost Time:0
clearData Cost Time:3.048
4.3 使用erase
In Clear Cost Time:2.005
clearData Cost Time:2.007
In Clear Cost Time:2.317
clearData Cost Time:2.363
In Clear Cost Time:3.113
clearData Cost Time:3.113
In Clear Cost Time:2.45
clearData Cost Time:2.45
In Clear Cost Time:2.52
clearData Cost Time:2.521
In Clear Cost Time:2.937
clearData Cost Time:2.938
In Clear Cost Time:3.825
clearData Cost Time:3.825
In Clear Cost Time:3.646
clearData Cost Time:3.646
In Clear Cost Time:3.195
clearData Cost Time:3.196
In Clear Cost Time:3.554
clearData Cost Time:3.554
4.4 使用for erase
In Clear Cost Time:1.944
clearData Cost Time:1.944
In Clear Cost Time:2.091
clearData Cost Time:2.091
In Clear Cost Time:1.923
clearData Cost Time:1.924
In Clear Cost Time:1.985
clearData Cost Time:1.986
In Clear Cost Time:1.917
clearData Cost Time:1.918
In Clear Cost Time:2.248
clearData Cost Time:2.249
In Clear Cost Time:2.259
clearData Cost Time:2.259
In Clear Cost Time:2.649
clearData Cost Time:2.65
In Clear Cost Time:2.566
clearData Cost Time:2.566
In Clear Cost Time:2.56
clearData Cost Time:2.561
5. 测试结论
就单单实现某个map清空来说,swap效率最高,几乎是0耗时。但是当退出整个函数,释放swap转移到的临时对象要耗一定的时间。
erase效率稍微比clear高。通过for循环erase好似效率又高点。
6. 最后问题解决
基于测试的情况,采用swap,并把clearData函数放到另外一个线程中,这样它释放局部变量的耗时并不影响当前线程,加一个状态变量判定要释放的map已经被释放了就行。
修改后的系统流程如下: