Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;程序比使用cin更快?_C++_C_Performance_Io - Fatal编程技术网

C++ 在C++;程序比使用cin更快?

C++ 在C++;程序比使用cin更快?,c++,c,performance,io,C++,C,Performance,Io,我不知道这是不是真的,但当我在一个提供问题的网站上阅读常见问题时,我发现了一些东西,引起了我的注意: 检查您的输入/输出方法。在C++中,使用CIN和CUT太慢。使用这些,你将保证不能用相当数量的输入或输出来解决任何问题。改用printf和scanf 有人能澄清一下吗?在C++程序中使用ScFF()比使用CIN更快吗?如果是的话,在C++程序中使用它是一个好的实践吗?我认为它是C的,虽然我只是学习C++ +…/p>< p>即使代码> SCANF比CIN < /C> >快,也没关系。绝大多数情况下

我不知道这是不是真的,但当我在一个提供问题的网站上阅读常见问题时,我发现了一些东西,引起了我的注意:

检查您的输入/输出方法。在C++中,使用CIN和CUT太慢。使用这些,你将保证不能用相当数量的输入或输出来解决任何问题。改用printf和scanf


有人能澄清一下吗?在C++程序中使用ScFF()比使用CIN更快吗?如果是的话,在C++程序中使用它是一个好的实践吗?我认为它是C的,虽然我只是学习C++ +…/p>< p>即使代码> SCANF比CIN < /C> >快,也没关系。绝大多数情况下,你都是通过硬盘或键盘阅读。将原始数据导入应用程序所需的时间比处理原始数据所需的
scanf
cin
时间多出几个数量级。

可能scanf比使用流要快一些。尽管流提供了很多类型安全性,并且不必在运行时解析格式字符串,但它通常具有不需要过多内存分配的优势(这取决于编译器和运行时)。也就是说,除非性能是您唯一的最终目标,并且您处于关键路径,否则您应该真正支持更安全(更慢)的方法


Herb Sutter“”在这里写了一篇非常有趣的文章,详细介绍了字符串格式化程序的性能,如
sscanf
lexical_cast
,以及是什么样的事情使它们运行得缓慢或快速。这有点类似,可能是会影响C风格IO和C++风格之间的性能的事情。格式化程序的主要区别在于类型安全性和内存分配的数量。

问题在于
cin
涉及大量开销,因为它在
scanf()调用上方提供了一个抽象层。如果你正在编写C++软件,你就不应该使用<代码> SCAFF()/<代码> >代码> CIN <代码>。如果你想要性能,你可能不会在C++中写I/O。

< P>有STDIO实现(),它实现了文件*C++作为流式格式,FPRTFF作为运行时格式解析器。IOstreams不需要运行时格式解析,这都是在编译时完成的。所以,在共享后端的情况下,可以合理地预期iostreams在运行时会更快。

如果您同时关心性能和字符串格式,请查看该库


编辑——链接到该库中的accu出版物:

我刚刚花了一个晚上在UVa在线上解决了一个问题(FactoryVisors,一个非常有趣的问题,请查看):

我的意见书超过了时间限制。在这些解决问题的在线判断网站上,您有大约2-3秒的时间限制来处理用于评估解决方案的数千个测试用例。对于像这样的计算密集型问题,每微秒都很重要

我使用的是建议的算法(在该网站的论坛上阅读),但仍然有问题

我只是把“cin>>n>>m”改成了“scanf”(%d%d,&n,&m)”,把几个小“couts”改成了“printfs”,我的TLE变成了“Accepted”


因此,是的,它可以带来很大的不同,特别是在时间限制很短的情况下。

当然,在iostream上使用cstdio是荒谬的。至少当你开发软件(如果你已经在C++上使用C++,那么就一直走下去,使用它的好处,而不是仅仅忍受它的缺点)。 但是在网上判断你不是在开发软件,你是在创建一个程序,它应该能够在3秒内完成微软软件需要60秒才能完成的事情

因此,在这种情况下,黄金法则是这样的(当然,如果您使用java不会遇到更多的麻烦)

  • 使用C++,并使用它的所有电源(重/慢)来解决问题
  • 如果您有时间限制,那么更改printfs和scanfs的cins和couts (如果使用类字符串时出错,请按如下方式打印:printf(%s,mystr.c_str())
  • 如果您仍然受到时间限制,那么尝试进行一些明显的优化(例如避免过多的嵌入for/while/dowhile或递归函数)
  • 如果仍然有时间限制,请尝试更改c数组的std::vectors和set
  • 如果你仍然有时间限制,那么继续下一个问题

是,iostream比cstdio慢。
是的,如果你在C++中开发,你可能不应该使用CSTDIO。 话虽如此,如果您不关心格式、类型安全等等,那么有比scanf更快的方式获取I/O

例如,这是一个从STDIN获取数字的自定义例程:

inline int get_number()
{
    int c;        
    int n = 0;

    while ((c = getchar_unlocked()) >= '0' && c <= '9')
    {
        // n = 10 * n + (c - '0');
        n = (n << 3) + ( n << 1 ) + c - '0';
    }
    return n;
}
inline int get_number()
{
INTC;
int n=0;

while((c=getchar_unlocked())>='0'&&c这里有一个简单案例的快速测试:一个从标准输入读取数字列表并对所有数字进行异或的程序

iostream版本:

#include <iostream>

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

  int parity = 0;
  int x;

  while (std::cin >> x)
    parity ^= x;
  std::cout << parity << std::endl;

  return 0;
}
#include <stdio.h>

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

  int parity = 0;
  int x;

  while (1 == scanf("%d", &x))
    parity ^= x;
  printf("%d\n", parity);

  return 0;
}
iostream version:                       21.9 seconds
scanf version:                           6.8 seconds
iostream with sync_with_stdio(false):    5.5 seconds
更改编译器的优化设置似乎根本不会改变结果

因此:确实存在速度差异


编辑:用户clyfish认为速度差异主要是由于iostream I/O函数与C I/O函数保持同步。我们可以通过调用
std::ios::sync_with_stdio(false);

C++iostream获胜!事实证明,这种内部同步/刷新通常会减慢iostream i/o的速度。如果我们不混合使用stdio和iostream,我们可以将其关闭,然后iostream速度最快

代码:

性能
#include <iostream>

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

  int parity = 0;
  int x;

  std::ios::sync_with_stdio(false);

  while (std::cin >> x)
    parity ^= x;
  std::cout << parity << std::endl;

  return 0;
}
iostream version:                       21.9 seconds
scanf version:                           6.8 seconds
iostream with sync_with_stdio(false):    5.5 seconds
std::ios::sync_with_stdio(false);
std::ios::sync_with_stdio(false);
#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;
}
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