簡體   English   中英

在c ++中讀取csv文件的最快方法,它包含大量的列和行

[英]The fastest way to read csv file in c++ which contains large no of columns and rows

我有一個管道分隔的數據文件超過13列。 總文件大小超過100 MB。 我正在讀取每一行,將字符串拆分為std::vector<std::string>以便我可以進行計算。 我對文件中的所有行重復此過程,如下所示:

    string filename = "file.dat";
    fstream infile(filename);
    string line;
    while (getline(infile, line)) {
        string item;
        stringstream ss(line);
        vector<string> splittedString;
        while (getline(ss, item, '|')) {
            splittedString.push_back(item);
        }
        int a = stoi(splittedString[0]); 
        // I do some processing like this before some manipulation and calculations with the data
    }

然而,這非常耗時,我很確定它不是讀取CSV類型文件的最佳方式。 如何改進?

更新

我嘗試使用boost::split函數而不是while循環,但它實際上甚至更慢。

您沒有CSV文件,因為CSV代表您沒有的逗號分隔值。
您有一個分隔的文本文件(顯然由"|"分隔)。 解析CSV更簡單,只需拆分","

無論如何,如果沒有太多戲劇性的變化,這里有一些建議:

  • 使用(更多)緩沖
  • vector移出循環並在每次迭代中clear()它。 這將節省堆重新分配。
  • 使用string::find()而不是stringstream來拆分字符串。

像這樣......

using namespace std;
int main() {
    string filename = "file.dat";
    fstream infile(filename);
    char buffer[65536];
    infile.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
    string line;
    vector<string> splittedString;
    while (getline(infile, line)) {
        splittedString.clear();
        size_t last = 0, pos = 0;
        while ((pos = line.find('|', last)) != std::string::npos) {
            splittedString.emplace_back(line, last, pos - last);
            last = pos + 1;
        }
        if (last)
            splittedString.emplace_back(line, last);
        int a = stoi(splittedString[0]);
        // I do some processing like this before some manipulation and calculations with the data
    }
}

通過消除“vector splittedString;”可以節省另外50% 並使用strtok_s()進行就地解析

int main() {
auto t1 = high_resolution_clock::now();
long long a(0);

string filename = "file.txt";
fstream infile(filename);
char buffer[65536];
infile.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
string line;
while (getline(infile, line)) {

    char * pch = const_cast<char*>(line.data());
    char *nextToken = NULL;
    pch = strtok_s(pch, "|", &nextToken);
    while (pch != NULL)
    {
        a += std::stoi(pch);
        pch = strtok_s(NULL, "|", &nextToken);
    }
}

auto t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(t2 - t1).count();
std::cout << duration << "\n";
std::cout << a << "\n";

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM