【问题标题】:How to increase file reading speed?如何提高文件读取速度?
【发布时间】:2016-11-23 09:11:08
【问题描述】:

我有超过一百万行的大型 .txt 文件,每行包含 7 列浮点数。列通过空格分隔。

目前,我通过读取每一行(getline)来导入文件,将行转换为流,然后将七个值存储到数组变量中(请参阅我的最小示例)。但是,此过程非常缓慢,300 万行 (500MB) 大约需要 10 分钟。这相当于 0.8 MB/s,比写入文件要慢得多。我的硬盘是 SSD。

您能给我建议如何提高代码的效率吗?

最佳,费边

C++

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

struct Container { double a, b, c, d, e, f, g; };

void read_my_file(std::ifstream &file, Container *&data) {
    std::string line;
    std::stringstream line_as_stream;
    unsigned int column;
    unsigned long int row;

    data = new Container[300000]; //dynamically allocated because the 
                                  //length is usually a user input.

    for (row = 0; row < 300000; row++) {
        getline(file, line);
        line_as_stream.str(line);

        for (column = 0; column < 7; column++) {
            line_as_stream >> data[row].a;
            line_as_stream >> data[row].b;
            line_as_stream >> data[row].c;
            line_as_stream >> data[row].d;
            line_as_stream >> data[row].e;
            line_as_stream >> data[row].f;
            line_as_stream >> data[row].g;
        }

        line_as_stream.clear();
    }
}

int main(void) {
    Container *data = nullptr;
    std::ifstream file;

    file.open("./myfile.txt", std::ios::in);
    read_my_file(file, data);
    std::cout << data[2].b << "\n";

    file.close();

    return 0;
}

【问题讨论】:

  • 这个答案Efficiently reading a very large text file in C++ 看起来很相关。
  • 为什么不尝试直接使用file &gt;&gt; some_string;,而不是先复制到stringstream
  • 另外,您是否正在为您的应用程序的发布、优化构建计时?或者它是一个“调试”、未优化的版本?
  • 每秒可以读取数百万行。处理行的时间,而不是 I/O。
  • 写入速度很快,将数据复制到文件系统缓存中,稍后再写入磁盘。除非你有一台时光机,否则阅读不会那么快。大量 RAM 并在文件写入后立即启动程序会有所帮助。但是 800 KB/sec 显然太慢了,&lt;iostream&gt; 通常不适合快速 I/O。它的设计没有考虑关于 std::locale 太弱的线程和标准承诺。使其线程安全是昂贵的,许多细粒度的锁会杀死性能。使用分析器,这样我们就不必猜测了。

标签: c++ file-io io getline stringstream


【解决方案1】:

我认为这是因为默认情况下 C++ 不是缓冲流。所以在第一个循环中你只得到一条线(因为它没有缓冲),通过迭代你一次又一次地访问硬盘驱动器(这会很慢)。you may want to look at this question, it might help you.

【讨论】:

  • 嗯,C++ 流默认缓冲,直接或通过stdio(被缓冲);此外,即使是操作系统也会缓冲读取,因此他实际上不太可能连续访问磁盘。
  • hımm,我不知道。缓冲区大小可能很小吗?如果是这样,手动更改缓冲区大小可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2015-06-15
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
相关资源
最近更新 更多