从文件中解析原始数据的最快、最高效的方法

Fastest and efficient way of parsing raw data from file

本文关键字:高效 方法 原始数据 文件      更新时间:2023-10-16

我正在做一些项目,我想知道哪种方式从文件中读取大量数据最有效(我说的是100行到30亿行的文件,可以考虑更多)。读取后,数据将存储在结构化数据集中(vector<entry>,其中"条目"定义结构化行)。

此文件的结构化行可能如下所示:string int int int string string其也以适当的平台CCD_ 3结束并且是TAB定界的

我希望完成的是:

  1. 将文件读入内存(string)或vector<char>
  2. 从缓冲区读取原始数据,并将其格式化为数据集

我需要考虑内存占用,并具有快速解析率。我已经避免使用stringstream了,因为它们看起来太慢了。

我还通过使用避免了对我的文件的多次I/O调用

// open the stream
std::ifstream is(filename);
// determine the file length
is.seekg(0, ios_base::end);
std::size_t size = is.tellg();
is.seekg(0, std::ios_base::beg);
// "out" can be a std::string or vector<char>
out.reserve(size / sizeof (char));
out.resize(size / sizeof (char), 0);
// load the data
is.read((char *) &out[0], size);
// close the file
is.close();

我曾想过用这个巨大的std::string,然后逐行循环,我会将行信息(字符串和整数部分)提取到我的数据集中行中。有更好的方法吗?

编辑:此应用程序可以在32位、64位计算机上运行,也可以在超级计算机上运行以获取更大的文件。

欢迎提出任何建议。

谢谢

一些随机的想法:

  • 在开始时使用vector::resize()(您做到了)
  • 一次读取大块的文件数据,至少4k,最好是256k。将它们读取到内存缓冲区中,并将该缓冲区解析为向量
  • 不要一次读取整个文件,这可能会导致不必要的交换
  • sizeof(char)始终为1:)

虽然我不能代表有3条千兆线的超级计算机,但在台式机的内存中,你将一事无成。

我认为你应该首先尝试弄清楚对这些数据的所有操作。您应该尝试将所有算法设计为按顺序操作。如果你需要随机访问,你会一直进行交换。这种算法设计将对您的数据模型产生重大影响。

因此,不要从读取所有数据开始,因为这是一个容易的部分,而是在设计整个系统时要清楚地了解整个处理过程中内存中的数据。


更新
当您在流上的单次运行中执行所有处理并将数据处理分阶段(读取-预处理-…-写入)进行时,您可以有效地利用多线程。


最终

  • 无论你想在数据循环中做什么,都要尽量减少循环次数。求平均值,确保在读取循环中可以做到
  • 立即制作一个测试文件,大小和时间是最差的两种方法

time
loop
read line from disk
time
loop
process line (counting words per line)
time
loop
write data (word count) from line to disk
time

与。

time
loop
read line from disk
process line (counting words per line)
write data (word count) from line to disk
time

如果你有已经使用你的算法。否则就补一个(比如每行数单词)。如果写作阶段不适用于你的问题,跳过它。这个测试确实需要不到一个小时的写作时间,但可以为你节省很多。