正在读大.csv文件?

时间:2017-11-26 14:35:48

标签: c++ csv

我正在尝试读取一个大约有五万行的.csv文件。在下面的代码中,我一次读取每一行,将其解析为预定义的结构,称为NinjaInfo_t,然后将其推送到列表中。阅读这个文件的整个过程花了我超过1分钟。还有另一种方式让它更快吗?这也是一个功课,所以我不能使用任何支持读取csv文件的库,我必须使用链表来存储数据。

ifstream is("data.csv",ifstream::binary);
is.seekg(0, ios_base::end);
size_t size = is.tellg();
is.seekg(0, ios_base::beg);
char* buffer = new char[size];
is.read(buffer, size);
stringstream ss;
ss.str(buffer);
// skip the file line in data.csv
string data;
getline(ss, data);
while (getline(ss, data)) {
    NinjaInfo_t newData;
    stringstream dataStream;
    dataStream.str(data);
    string tmp;
    string timestamp;
    string id;
    string longtitude, latitude;

    getline(dataStream, tmp, ',');
    getline(dataStream, timestamp, ',');
    getline(dataStream, id, ',');
    getline(dataStream, longtitude, ',');
    getline(dataStream, latitude, ',');
    getline(dataStream, tmp);

    istringstream(longtitude) >> newData.longitude;

    istringstream(latitude) >> newData.latitude;

    while (id.length() < 4) {
        id = '0' + id;
    }
    istringstream(id) >> newData.id;

    stringstream ss;
    struct tm _tm = {};

    string t = timestamp;
    ss.str(t);
    ss >> std::get_time(&_tm, "%d/%m/%Y %H:%M:%S");
    _tm.tm_isdst = -1;
    time_t time = std::mktime(&_tm);
    newData.timestamp = time;
    db.push_back(newData); //DB IS A LINKED LIST.

P.s:抱歉英语不好:P。

1 个答案:

答案 0 :(得分:1)

表现不佳有两个主要原因:

  • 通过在每次迭代(即构造函数/初始化/析构函数)创建抛弃istringstream而不是仅仅进行转换(例如使用std::stoi()和{{3>来产生大量开销}})。
  • push_back()每个记录到db向量(我假设)。但随着它的大小增加,它需要频繁的重新分配和移动它包含的数据。你可以在开始时reserve()预期的空间,只是为了减少这种内存管理开销。

注1:目前尚不清楚,如果一次读取文件会带来显着的性能提升,因为文件流无论如何都会被缓冲。

注意2:请注意,您的CSV处理与alike没有完全一致,这样可以将数据中的换行符括在引号之间。