代码有效吗?

时间:2015-03-31 11:27:46

标签: c++ visual-c++

我的combinedata.csv文件有11230909行,文件大小约为1.6GB。当我尝试加载它并将向量字符串构造成C ++时,这需要超过5个小时。

我的代码不是最佳的还是时间效率的。如何减少时间到尽可能多。知道导入1.6GB文件并创建变量需要多少优化代码。

#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<ctime>


using namespace std;
vector <string> data;

vector <string> readcsvfile()
{   
string line, val;   
ifstream file("combinedata.csv");

while (!file.eof())
{    
    getline(file, line);

    if (!file.good())
        break;
    stringstream newline(line);
    newline << line + ",\n";

    if (!newline.good())
        break;

    while (getline(newline, val, ','))
    {
        if (val != "NA")
            data.push_back(val);
        else
            break;
    }

}

return data;
}

void main()
{
vector <string> data;
data = readcsvfile();
cout << data.size();
cin.get();
}

3 个答案:

答案 0 :(得分:1)

  

我的代码不是最佳的还是时间效率的。

不是。 std::vectorstd::string机会性地分配内存,这意味着当您填充向量时,您将获得大量重新分配(每个重新分配大于下一个)。

我认为这是您尝试过的C和C ++代码之间的主要区别:在C中,您没有针对不同用例优化的花哨结构(即与读取1.6 Gb文件不同)。

  

如何将时间减少到尽可能多的时间。知道导入1.6GB文件并创建变量需要多少最佳代码。

不知道它需要多少“最佳代码”:(

为减少处理时间,尝试不同的算法来读取数据,并测量效率;我会尝试两件事:

  • 将文件读取为二进制文件并手动解析;
  • 传递一次并计算字符串/大小,然后预先分配结果空间,然后第二次传递并读取数据。

答案 1 :(得分:0)

不是答案,但我现在就把它放在这里,因为它不会发表评论:

:此...

while(!file.eof())
{    
    getline(file, line);

    if(!file.good())
        break;

    // ...
}

...可以更简单地完成:

while(getline(file, line))
{    
    // ...
}

答案 2 :(得分:0)

您的代码不是最佳的,但我不认为这是您的问题,我认为这是您的文件大小更多的问题。如果你想做更好的代码,你可以:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

void main(){
    vector<string> data;

    copy_if(istream_iterator<string>(ifstream("combinedata.csv")),
            istream_iterator<string>(),
            back_inserter(data),
            [](const string& i){return i != "NA";});
}

正如utnapistim指出的那样,这在gcc 5.0之前的gcc中不起作用,因为有一个bug with moving streams。这似乎不是因为你使用的void main只有Visual Studio支持。但对于那些 工作在5.0以上的gcc的人来说,你可以通过将main的正文替换为:

来实现这一点。
vector<string> data;
ifstream file("combinedata.csv");

copy_if(istream_iterator<string>(file),
        istream_iterator<string>(),
        back_inserter(data),
        [](const string& i){return i != "NA";});