我试图将csv文件读入包含字符串向量向量的结构中.该文件包含大约200万行,磁盘大小约为350 mb.当我将文件读入struct时top显示我正在读取完整文件,该程序现在使用了近3.5GB的内存.我使用向量保留来尝试限制push_back上的向量容量增加.
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<fstream>
#include<string.h>
#include<sstream>
#include<math.h>
#include<vector>
#include<algorithm>
#include<array>
#include<ctime>
#include<boost/algorithm/string.hpp>
using namespace std;
struct datStr{
vector<string> colNames;
vector<vector<string>> data;
};
datStr readBoost(string fileName)
{
datStr ds;
ifstream inFile;
inFile.open(fileName);
string line;
getline(inFile, line);
vector<string> colNames;
stringstream ss(line);
string item;
int i = 0;
vector<int> colTypeInt;
while(getline(ss, item, ','))
{
item.erase( remove( item.begin(), item.end(), ' ' ), item.end() );
colNames.push_back(item);
vector<string> colVec;
ds.data.push_back(colVec);
ds.data[i].reserve(3000000);
i++;
}
int itr = 0;
while(getline(inFile, line))
{
vector<string> rowStr;
boost::split(rowStr, line, boost::is_any_of(","));
for(int ktr = 0; ktr < rowStr.size(); ktr++)
{
rowStr[ktr].erase( remove( rowStr[ktr].begin(), rowStr[ktr].end(), ' ' ), rowStr[ktr].end() );
ds.data[ktr].push_back(rowStr[ktr]);
}
itr++;
}
int main()
{
datStr ds = readBoost("file.csv");
while(true)
{
}
}
Run Code Online (Sandbox Code Playgroud)
PS:最后一个while是这样我可以在完成程序时监视内存使用情况.这是在使用矢量时预期的事情还是我在这里遗漏了什么?另一个有趣的事实 我开始在读取循环中为每个字符串添加大小和容量.令人惊讶的是,它只增加了我在ubuntu顶部显示的1/10?可能是top是误报还是我的编译器分配了太多空间?
我用一个1886850包含文本行的输入文件测试了你的代码,其大小为105M.
使用您的代码,内存消耗约为2.5G.
然后,我开始修改数据的存储方式.
第一次测试:
更改datStr到:
struct datStr{
vector<string> colNames;
vector<string> lines;
};
Run Code Online (Sandbox Code Playgroud)
这减少了内存消耗206M.这大小减少了10倍以上.很明显,使用的惩罚
vector<vector<string>> data;
Run Code Online (Sandbox Code Playgroud)
相当僵硬.
第二次测试:
更改datStr到:
struct datStr{
vector<string> colNames;
vector<string> lines;
vector<vector<string::size_type>> indices;
};
Run Code Online (Sandbox Code Playgroud)
与indices跟踪这个标记的lines开始.您可以使用lines和从每行中提取标记indices.
随着这种变化,内存消耗量增加,543MB但是比原来的小五倍.
第三次测试
更改dataStr到:
struct datStr{
vector<string> colNames;
vector<string> lines;
vector<vector<unsigned int>> indices;
};
Run Code Online (Sandbox Code Playgroud)
随着这种变化,内存消耗降到了455MB.如果您不希望您的线条更长或更长,这应该有效UINT_MAX.
第四次测试
更改dataStr到:
struct datStr{
vector<string> colNames;
vector<string> lines;
vector<vector<unsigned short>> indices;
};
Run Code Online (Sandbox Code Playgroud)
随着这种变化,内存消耗降到了278MB.如果您不希望您的线条更长或更长,这应该有效USHRT_MAX.对于这种情况,开销indices只是很小72MB.
这是我用于测试的修改代码.
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<fstream>
#include<string.h>
#include<sstream>
#include<math.h>
#include<vector>
#include<algorithm>
#include<array>
#include<ctime>
// #include<boost/algorithm/string.hpp>
using namespace std;
struct datStr{
vector<string> colNames;
vector<string> lines;
vector<vector<unsigned short>> data;
};
void split(vector<unsigned short>& rowStr, string const& line)
{
string::size_type begin = 0;
string::size_type end = line.size();
string::size_type iter = begin;
while ( iter != end)
{
++iter;
if ( line[iter] == ',' )
{
rowStr.push_back(static_cast<unsigned short>(begin));
++iter;
begin = iter;
}
}
if (begin != end )
{
rowStr.push_back(static_cast<unsigned short>(begin));
}
}
datStr readBoost(string fileName)
{
datStr ds;
ifstream inFile;
inFile.open(fileName);
string line;
getline(inFile, line);
vector<string> colNames;
stringstream ss(line);
string item;
int i = 0;
vector<int> colTypeInt;
while(getline(ss, item, ','))
{
item.erase( remove( item.begin(), item.end(), ' ' ), item.end() );
ds.colNames.push_back(item);
}
int itr = 0;
while(getline(inFile, line))
{
ds.lines.push_back(line);
vector<unsigned short> rowStr;
split(rowStr, line);
ds.data.push_back(rowStr);
}
}
int main(int argc, char** argv)
{
datStr ds = readBoost(argv[1]);
while(true)
{
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
460 次 |
| 最近记录: |