【问题标题】:Which is faster and more efficient, processing char by char as char or as stream?哪个更快,更有效,将 char 按 char 处理为 char 还是作为流?
【发布时间】:2015-08-13 10:05:09
【问题描述】:

如果我想在使用之前逐个字符地处理文本文件。什么方法最有效?

我可以这样做:

ifstream ifs("the_file.txt", ios_base::in);
char c;
while (ifs >> noskipws >> c) {
    // process c ...
}
ifs.close();

还有这个:

ifstream ifs("the_file.txt", ios_base::in);
stringstream sstr;
sstr << ifs.rdbuf();
string txt = sstr.str();
for (string::iterator iter = txt.begin(); iter != txt.end(); ++iter) {
    // process *iter ...
}

最终输出将根据迭代时找到的字符拆分字符串。

哪个更快?或者也许还有另一种更有效的方法?我是否需要为每个字符刷新stringstream(我在某处读到flush 正在影响性能)?

【问题讨论】:

  • 我认为您在这里进行了过早的优化。尝试这两种情况,分析和优化。我觉得这取决于编译器的实现,甚至可能取决于操作系统。
  • 你应该尝试测量两者。

标签: c++ string stream flush


【解决方案1】:

a) 度量(我猜第一个应该更快,因为它避免了额外的分配,但这只是一个猜测)

b) 虽然过早优化确实是一个非常糟糕的情况,但如果您确实需要最佳性能,请尝试以下方式:

int f = open(...);
//error handling here
char buf[256];
while(1) {
  int rd = read(f,buf,256);
  if( rd == 0 ) break;
  for(const char*p=buf;p<buf+rd;++p) {
    //process *p; note that this loop can be entered more than once
  }
}
close(f);

我很确定要在性能方面击败这段代码是非常困难的(除非进入非常低级的非标准 IO);但是,ifstream 很容易产生可比较的结果。或者它可能不会。

注意:对于 C++,这种技术(读取固定大小的缓冲区,然后是扫描缓冲区)提供的差异很小并且通常可以忽略不计,但对于其他语言,它可能很容易提供高达 2 倍的差异(已在 Java 上观察到)。

【讨论】:

    【解决方案2】:

    基于对 20 兆字节文件的粗略测试,此方法在 0.1 秒内将文件加载到一个字符串中,而您之前使用的 rdbuf 方法为 0.5 秒。因此,除非您访问大量文件,否则基本上没有区别。

    ifstream ifs(filename, ios::binary);
    string txt;
    unsigned int cursor = 0;
    const unsigned int readsize = 4096;
    while (ifs.good())
    {
        txt.resize(cursor + readsize);
        ifs.read(&txt[cursor], readsize);
        cursor += (unsigned int)ifs.gcount();
    }
    txt.resize(cursor);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2019-08-16
      • 2014-06-24
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多