将文件读入struct时,大小增加10倍

Nav*_*rma 5 c++ struct

我试图将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是误报还是我的编译器分配了太多空间?

R S*_*ahu 7

我用一个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)