在C++程序中使用scanf()比使用cin更快吗?

151

我不知道这是否属实,但当我在一个问题提供网站上阅读FAQ时,我发现了一些引起我注意的内容:

检查您的输入/输出方式。 在C ++中,使用cin和cout太慢了。 使用它们,您将无法解决任何具有适量输入或输出的问题。 而应该使用printf和scanf来代替。

能否有人澄清一下这个问题? 在C ++程序中,使用 scanf()比使用 cin >> something 快吗? 如果是的话,在C ++程序中使用它是一个好习惯吗? 我认为那只是 C语言 特有的,虽然我正在学习C ++...


我很好奇他们遇到了什么问题,以至于认为这会成为一个问题。你有那个网站的链接吗? - Eclipse
17
我的猜测是:不好的程序员会把标准库的性能问题归咎于标准库本身,这有点像那些总是喊着“我发现了GCC的bug”的幽默者。 - John Kugelman
12
@eclipse:我为比赛做过的ACM问题涉及大量输入/输出,你的程序必须在60秒内解决问题...这在这里成为了一个真正的问题。 - mpen
23
话虽如此,如果您需要依赖scanf()来获得额外的性能提升,那么您处理问题的方式是错误的 :) - mpen
这是关于cin的一些有趣事情(滚动到讨论其在实现中减速的部分):http://unthought.net/c++/c_vs_c++.html - Johannes Schaub - litb
4
作为一项观察,我进行了尝试,并且在第二个问题(PRIME1)中使用了相同的算法,在两种情况下都进行了尝试:一次使用cin/cout,一次使用scanf/printf。第一种版本比第二种更快(但足够接近以至于统计上没有差异)。这是被标记为输入/输出密集型的问题之一,然而输入/输出的方法在统计学上没有任何区别。 - Eclipse
12个回答

0
#include <stdio.h>
#include <unistd.h>

#define likely(x)       __builtin_expect(!!(x), 1)
#define unlikely(x)     __builtin_expect(!!(x), 0)

static int scanuint(unsigned int* x)
{
  char c;
  *x = 0;

  do
  {
      c = getchar_unlocked();
      if (unlikely(c==EOF)) return 1;
  } while(c<'0' || c>'9');

  do
  {
      //*x = (*x<<3)+(*x<<1) + c - '0';
      *x = 10 * (*x) + c - '0';
      c = getchar_unlocked();
      if (unlikely(c==EOF)) return 1;
  } while ((c>='0' && c<='9'));

  return 0;
}

int main(int argc, char **argv) {

  int parity = 0;
  unsigned int x;

  while (1 != (scanuint(&x))) {
    parity ^= x;
  }
  parity ^=x;
  printf("%d\n", parity);

  return 0;
}

文件末尾有一个错误,但是这段 C 代码比更快的 C++ 版本要快得多。

paradox@scorpion 3845568-78602a3f95902f3f3ac63b6beecaa9719e28a6d6 ▶ make test        
time ./xor-c < rand.txt
360589110

real    0m11,336s
user    0m11,157s
sys 0m0,179s
time ./xor2-c < rand.txt
360589110

real    0m2,104s
user    0m1,959s
sys 0m0,144s
time ./xor-cpp < rand.txt
360589110

real    0m29,948s
user    0m29,809s
sys 0m0,140s
time ./xor-cpp-noflush < rand.txt
360589110

real    0m7,604s
user    0m7,480s
sys 0m0,123s

原始的C++代码需要30秒,而C语言代码只需要2秒。


-5
即使 scanfcin 快,也没关系。大多数情况下,你将从硬盘或键盘读取数据。将原始数据传递到您的应用程序需要比 scanfcin 处理它花费更多的时间。

通过管道进行IPC怎么样?你认为那里可能会有明显的性能损失吗? - dreamlax
即使通过管道进行进程间通信,与仅使用scanf/cin解析相比,更多的时间都花费在内核中进出操作上。 - Jay Conrod
11
我在这个领域做了测试,可以肯定的是cout和cin会影响性能。虽然对于用户输入来说影响微乎其微,但对于那些性能至关重要的事情来说,情况就不一样了。不过还有其他更快的C++框架存在。 - Johannes Schaub - litb
2
问题在于 iostream 比硬盘慢。是的,它确实很糟糕。 - polkovnikov.ph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接