相信使用C++的人都有一种迷惑或者是不自信:在输入输出的时候是不是应该使用scanf/printf
更好呢,因为传说cin/cout
龟速,我当时也长期被这个所困扰,后来在阅读C++ primer第五版的时候我自己做了一个测试,发现如果不使用std::ios_sync_with_stdio(false);
关闭和C库函数的同步的话的确scanf/printf
快很多,大概相差五倍,但是如果关闭同步的话,cin/cout
是比scanf/printf
快8%-10%的。(这两个数据是我后面看别人测量的,我自己只是简单测量了一下)
之所以关闭缓冲以后cin/cout
比较快,是因为cin/cout
对输入参数和类型的推断是在编译时确定的,而scanf/printf
是在运行时确定的。
在我以前的一篇博客:C++Primer学习笔记:第1章 开始中我提到了这一点。
如果认为我自己的测量可能有误差,可以看一下大神们的回答:
Cin-Cout vs Scanf-Printf
Using scanf() in C++ programs is faster than using cin?
和我的说法是一致的,以后被人怼你怎么还用cin/cout
的时候,你可以拿出这些测评让他们瞧瞧,我们也应该对C++自信起来,不要想着C++没有C底层好像速度就差一些。
但是之前参加竞赛的时候,我信心满满地使用cin/cout
进行输入输出,却总是TEL,我以为是程序算法的问题,检查了好久好久,最后才发现是因为使用了cin/cout
的原因,改成scanf/printf
后程序就AC了,看到这里你是不是心里一惊:搞什么嘛,上面的测评都是唬人的嘛
其实之所以即使关闭了和C库的同步,我的程序还会TEL和cin/cout
没有什么关系,罪魁祸首是endl
,相信很多学习C++的人都和我一样,习惯了使用endl
进行换行,同时刷新缓冲区,一举两得,美滋滋,但是其实正是因为endl
会强制刷新缓冲区,导致频繁的IO操作,使得程序效率迅速降低。因此除非是使用打桩调试(就是及时输出调试信息,因为这里我们要求输出信息有时效性,所以要及时刷新缓冲区),否则都不要使用endl
,而使用\n
进行换行。
知道了这两点:
std::ios::sync_with_stdio(false);
cout << "Hello world" << "\n";
我们就可以放心地使用cin/cout
进行输入输出啦,而且效率肯定是最快的。
在使用cin
进行循环读入的时候可能会遇到一点问题,可以参考一下我以前写的一篇博客:C++ cin 实现循环读入
有了上面的准备,我们就可以使用cin/cout
开心地写代码啦。