【问题标题】:c++ reading file is too slowc++读取文件太慢
【发布时间】:2023-04-05 01:28:02
【问题描述】:

我正在尝试读取 ~36KB,完成此循环需要 ~20 秒:

ifstream input_file;

input_file.open("text.txt");
if( !(input_file.is_open()) )
{
    cout<<"File not found";
    exit(1);
}

std::string line;
stringstream line_stream;   //to use << operator to get words from lines

int lineNum=1;

while( getline(input_file,line) )   //Read file line by line until file ends
{
    line_stream.clear();    //clear stream
    line_stream << line;    //read line
    while(line_stream >> word)  //Read the line word by word until the line ends
    {
        //insert word into a linked list...
    }
    lineNum++;
}
input_file.close();

任何帮助将不胜感激。

【问题讨论】:

  • 事实上,问题可能是您插入到链表中。它可能是 O(n^2),这取决于它是如何实现的。而对于 36kB,“n”可能会很大。
  • 你是对的!我评论了插入部分,代码暂时结束了……我现在就去找问题。谢谢:)

标签: c++ stream


【解决方案1】:

stringstream::clear() 不会清除其中的所有上下文。它只会重置错误和 EOF 标志,请参阅 http://en.cppreference.com/w/cpp/io/basic_ios/clear

结果是您的line_stream 累积所有先前的行,内部循环将一次又一次地在所有累积的行上运行单词。

因此,与预期的 O(n) 相比,您花费的总时间约为 O(n^2)。

您可以在 while 循环中定义新的 line_stream 实例,而不是在每一行中使用相同的对象,以拥有一个全新的并且也是空的。像这样:

fstream input_file;

input_file.open("text.txt");
if( !(input_file.is_open()) )
{
    cout<<"File not found";
    exit(1);
}

std::string line;

int lineNum=1;

while( getline(input_file,line) )   //Read file line by line until file ends
{
    stringstream line_stream;   // new instance, empty line.
    line_stream << line;    //read line
    while(line_stream >> word)  //Read the line word by word until the line ends
    {
        //insert word into a linked list...
    }
    lineNum++;
}
input_file.close();

【讨论】:

  • 另一种重置字符串流的干净方法:line_stream.str(std::string());
  • 因此,您可以使用line_stream.str(line); 重置流并跳过&lt;&lt; 插入。
  • 谢谢,但它仅将时间缩短了约 4 秒,.. 整个代码需要约 24 秒.. 这需要约 20 秒...
  • 此时可能是您的存储总线有问题?你有很多其他的 I/O 吗? (即使文件很小,您是否检查过它在驱动器上是并发的?)
  • 是的,我发现类插入成员函数需要花费大量时间。
【解决方案2】:

您可以尝试以下方法:

std::ifstream file("text.txt");
std::string str;

while (std::getline(file, str))
{
    cout << str; //call function to to retrieve words of str in memory not in file 
}

我在 11 毫秒内运行了您的代码,但在 8 毫秒内使用了上述选项。可能对你有用。

【讨论】:

    【解决方案3】:

    尝试使用构建标志-O2-O3 进行编译。

    我惊讶地发现,读取 1GB 文件的简单 for 循环需要 4.7 秒,而另一种高级语言 (Dart) 则需要 3.x 秒。

    启用此标志后,运行时间降至 2.1 秒。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多