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

时间:2012-12-02 20:36:59

标签: c++ performance multiplatform

我正在研究一些项目,我想知道从文件中读取大量数据的最有效方法是什么(我说的是100行到3亿行的文件,可以更多的想法)。读取后,数据将存储在结构化数据集中vector<entry>,其中“条目”定义结构化线条。

此文件的结构化行可能如下所示:   string int int int string string 它也以适当的平台EOL结束,并以TAB分隔

我希望实现的目标是:

  1. 将文件读入内存(string)或vector<char>
  2. 从我的缓冲区中读取原始数据并将其格式化为我的数据集。
  3. 我需要考虑内存占用并且具有快速解析速率。 我已经避免使用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位计算机上运行,​​也可以在超级计算机上运行以获取更大的文件。

    非常欢迎任何建议。

    谢谢

2 个答案:

答案 0 :(得分:0)

一些随意的想法:

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

答案 1 :(得分: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

如果您已经使用了算法。否则组成一个(就像每行计数一样)。如果写阶段不适用于您的问题,请跳过它。这个测试确实需要不到一个小时的时间来编写,但可以为您节省很多。