假设您要将大文本文件(~300mb)中的数据读取到向量数组:vector<string> *Data
(假设列数已知)。
//file is opened with ifstream; initial value of s is set up, etc...
Data = new vector<string>[col];
string u;
int i = 0;
do
{
istringstream iLine = istringstream(s);
i=0;
while(iLine >> u)
{
Data[i].push_back(u);
i++;
}
}
while(getline(file, s));
此代码适用于小文件(&lt; 50mb),但在读取大文件时,内存使用量呈指数级增长。我很确定问题是每次在循环中创建istringstream
个对象。但是,在两个循环之外定义istringstream iLine;
并将每个字符串放入iLine.str(s);
流并在内部while循环(iLine.str(""); iLine.clear();
)之后清除流导致同样的内存爆炸顺序。
出现的问题:
istringstream
表现得这样; 谢谢
编辑:关于第一个答案,我稍后在代码中清理数组分配的内存:
for(long i=0;i<col;i++)
Data[i].clear();
delete []Data;
完整的COMPILE-READY CODE(添加标题):
int _tmain(int argc, _TCHAR* argv[])
{
ofstream testfile;
testfile.open("testdata.txt");
srand(time(NULL));
for(int i = 1; i<1000000; i++)
{
for(int j=1; j<100; j++)
{
testfile << rand()%100 << " ";
}
testfile << endl;
}
testfile.close();
vector<string> *Data;
clock_t begin = clock();
ifstream file("testdata.txt");
string s;
getline(file,s);
istringstream iss = istringstream(s);
string nums;
int col=0;
while(iss >> nums)
{
col++;
}
cout << "Columns #: " << col << endl;
Data = new vector<string>[col];
string u;
int i = 0;
do
{
istringstream iLine = istringstream(s);
i=0;
while(iLine >> u)
{
Data[i].push_back(u);
i++;
}
}
while(getline(file, s));
cout << "Rows #: " << Data[0].size() << endl;
for(long i=0;i<col;i++)
Data[i].clear();
delete []Data;
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << elapsed_secs << endl;
getchar();
return 0;
}
答案 0 :(得分:0)
我严重怀疑这不是istringstream问题(特别是,考虑到你在循环之外的iLine构造函数有相同的结果)。
可能这是std :: vector的正常行为。为了测试它,你如何运行完全相同的行,但注释掉:Data[i].push_back(u);
。看看你的记忆是否以这种方式增长。如果没有,那么你知道问题出在哪里..
取决于您的库,vector :: push_back每次需要更多空间时,其容量将扩大1.5倍(微软)或2倍(glib)。
答案 1 :(得分:0)
vector<>
以几何方式增长记忆。典型的模式是,只要需要增长,它就会使容量翻倍。如果您的循环在此阈值之后立即结束,那么可能会留下大量额外空间但未使用。完成后,您可以尝试在每个向量上调用shrink_to_fit()
。
此外,由C ++分配器(甚至是普通malloc()
)分配的内存通常不会返回给操作系统,而是留在进程内部空闲内存池中。这可能会导致进一步明显的增长。并且它可能导致shrink_to_fit()
的结果在流程外部不可见。
最后,如果你有很多小字符串(“2位数字”),string
对象的开销可能相当大。即使实现使用小字符串优化,我也假设一个典型的字符串使用不少于16或24个字节(大小,容量,数据指针或小字符串缓冲区) - 在{{1}的平台上可能更多是64位。这是3字节有效载荷的大量内存。
所以我假设你看到了size_type