我正在尝试读取一个大约有五万行的.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。
答案 0 :(得分:1)
表现不佳有两个主要原因:
istringstream
而不是仅仅进行转换(例如使用std::stoi()
和{{3>来产生大量开销}})。 push_back()
每个记录到db
向量(我假设)。但随着它的大小增加,它需要频繁的重新分配和移动它包含的数据。你可以在开始时reserve()
预期的空间,只是为了减少这种内存管理开销。注1:目前尚不清楚,如果一次读取文件会带来显着的性能提升,因为文件流无论如何都会被缓冲。
注意2:请注意,您的CSV处理与alike没有完全一致,这样可以将数据中的换行符括在引号之间。