Search code examples
c++ifstreamgetlineistringstream

ifstream, getline, and istringstream slow performance on big file in c++


I want to ask about my code below: (The code below basically read an input file named inputVelocity.dat with format stated in the code. The code reads with istringstream to pass each value to each particular arrays)

std::ifstream inputVelocity("input/inputVelocity.dat");
std::string lineInputVelocity;
while (std::getline(inputVelocity, lineInputVelocity))  {
  std::istringstream issVelocity(lineInputVelocity);
  double a, b, c, d, e;

  if (!(issVelocity >> a >> b >> c >> d >> e))  {
    std::cout << "ISS ERROR" << std::endl;
  }

  for (int k=0; k<=nz+1; k++)  {
    for (int j=0; j<=ny+1; j++)  {
      for (int i=0; i<=nx+1; i++)  {
        ux[i][j][k]     =   a;
        uy[i][j][k]     =   b;
        uz[i][j][k]     =   c;
        pressure[i][j][k]   =   d;
        temperature[i][j][k]    =   e;
      }
    }
  }
}

inputVelocity.close();

The code is fine when reading around 20000 lines, but when I change the file into around 1.6 million lines, the code run very slow even on a server.

I did std::cout on each getline loop and it read like 5 lines/second, with around 1.6 million lines.

I have found some related questions here but still can't understand what's the problem source and how to fix it. Anyone can help? Thank you.


Solution

  • I changed the code into this:

    std::ifstream inputVelocity("input/inputVelocity.dat");
    std::string lineInputVelocity;
    int getI, getJ, getK;
    getI = 0;
    getJ = 0;
    getK = 0;
    while (std::getline(inputVelocity, lineInputVelocity))  {
      std::istringstream issVelocity(lineInputVelocity);
      double a, b, c, d, e;
    
      if (!(issVelocity >> a >> b >> c >> d >> e))  {
        std::cout << "ISS ERROR" << std::endl;
      }
      std::cout << getI << " " << getJ << " " << getK << std::endl;
      ux[getI][getJ][getK]              =   a;
      uy[getI][getJ][getK]              =   b;
      uz[getI][getJ][getK]              =   c;
      pressure[getI][getJ][getK]        =   d;
      temperature[getI][getJ][getK]     =   e;
    
      getK = getK + 1;
    
      if (getK == nz+2)  {
        getJ = getJ + 1;
        getK = 0;
      }
    
      if (getJ == ny+2)  {
        getI = getI + 1;
        getJ = 0;
      }
    
    }
    
    inputVelocity.close();
    

    And that worked really well :) If anyone has a more efficient solution, I would be very glad to see! :)