1

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

此文件的结构化行可能如下所示: string int int int string string 它也以适当的平台结尾,EOL并以 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 位计算机上运行,​​或者在超级计算机上运行更大的文件。

任何建议都非常受欢迎。

谢谢

4

2 回答 2

0

一些随意的想法:

  • 在开始时使用 vector::resize() (你这样做了)
  • 一次读取大块文件数据,至少 4k,最好是 256k。将它们读入内存缓冲区,将该缓冲区解析为您的向量。
  • 不要一次读取整个文件,这可能会导致不必要的交换。
  • sizeof(char) 始终为 1 :)
于 2012-12-02T20:49:18.330 回答
0

虽然我不能代表具有 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

如果你有算法已经使用你的。否则组成一个(比如每行计算单词)。如果写入阶段不适用于您的问题,请跳过它。这个测试确实花费你不到一个小时的时间来写,但可以为你节省很多。

于 2012-12-02T21:44:21.443 回答