我不知道这是否属实,但当我在一个问题提供网站上阅读FAQ时,我发现了一些引起我注意的内容:
检查您的输入/输出方式。 在C ++中,使用cin和cout太慢了。 使用它们,您将无法解决任何具有适量输入或输出的问题。 而应该使用printf和scanf来代替。
能否有人澄清一下这个问题? 在C ++程序中,使用 scanf()比使用 cin >> something 快吗? 如果是的话,在C ++程序中使用它是一个好习惯吗? 我认为那只是 C语言 特有的,虽然我正在学习C ++...
我不知道这是否属实,但当我在一个问题提供网站上阅读FAQ时,我发现了一些引起我注意的内容:
检查您的输入/输出方式。 在C ++中,使用cin和cout太慢了。 使用它们,您将无法解决任何具有适量输入或输出的问题。 而应该使用printf和scanf来代替。
能否有人澄清一下这个问题? 在C ++程序中,使用 scanf()比使用 cin >> something 快吗? 如果是的话,在C ++程序中使用它是一个好习惯吗? 我认为那只是 C语言 特有的,虽然我正在学习C ++...
这是一个简单情况的快速测试:一个从标准输入读取数字列表并对所有数字进行XOR的程序。
使用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;
}
scanf版本:
#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;
}
结果
我使用第三方程序生成了一个包含33,280,276个随机数的文本文件。执行时间如下:
iostream version: 24.3 seconds
scanf version: 6.4 seconds
调整编译器的优化设置似乎并没有显著改变结果。
因此: 确实存在速度差异。
编辑: 用户clyfish在下面指出,速度差异主要是由于iostream I/O函数与C I/O函数维护同步。我们可以通过调用std::ios::sync_with_stdio(false);
来关闭同步:
#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
C++ iostream胜出!原来内部同步/刷新是导致iostream I/O通常变慢的原因。如果我们不混用stdio和iostream,可以关闭它,这样iostream是最快的。
scanf
调用中解析多个整数时,iostream
会失去优势。 - Maxim Egorushkinhttp://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
使用 cin
/cout
时,它们需要与底层C库保持同步,因此性能可能较慢。如果只使用C++ IO,可以在任何IO操作之前使用以下代码。
std::ios::sync_with_stdio(false);
如需了解更多信息,请查看相应的libstdc++文档。
也许scanf比使用流略快一些。虽然流提供了很多类型安全性,并且不必在运行时解析格式字符串,但通常它有一个优点,即不需要过多的内存分配(这取决于您的编译器和运行时环境)。尽管如此,除非性能是您唯一的目标,并且您处于关键路径中,否则您应该真正青睐更安全(较慢)的方法。
这里有一篇非常美味的文章,由Herb Sutter撰写"The String Formatters of Manor Farm",详细介绍了字符串格式化程序(如sscanf和lexical_cast)的性能以及使其运行缓慢或快速的原因。这与C样式IO和C++样式之间的性能影响可能有类似之处。格式化程序的主要区别在于类型安全性和内存分配数量。
我刚刚花了一个晚上在UVa Online解决了一个问题(《因数分解器》,非常有趣的问题,请查看):
我的提交结果显示“超时”(TLE)。 在这些问题解决在线评测网站上,您有大约2-3秒的时间限制来处理可能达到数千个测试用例以评估您的解决方案。 对于像这样计算密集型的问题,每微秒都很重要。
我正在使用建议的算法(在该站点的讨论论坛中阅读),但仍然遇到TLE。
我只是将 “cin >> n >> m” 更改为 “scanf("%d %d", &n, &m)” 并将少量的 “couts” 更改为 “printfs”,我的TLE变成了“已接受”!
所以,是的,它可以有很大的影响,特别是当时间限制很短时。
如果你关注性能和字符串格式化,不妨看看Matthew Wilson的FastFormat库。
编辑--该库的ACCU出版物链接:http://accu.org/index.php/journals/1539
一般情况下,在C ++中使用的语句cin
和cout
似乎比scanf
和printf
慢,但实际上它们更快!
原因在于:在C ++中,每当您使用cin
和cout
时,默认情况下会发生同步过程,以确保如果您在程序中同时使用scanf
和cin
,它们将相互同步。这个同步过程需要时间。因此,cin
和cout
看起来比较慢。
然而,如果设置同步过程不发生,cin
比scanf
快。
要跳过同步过程,请在程序的开头的main()
中包含以下代码片段:
std::ios::sync_with_stdio(false);
欲了解更多信息,请访问此网站。
有一些stdio实现(libio)将FILE*实现为C++ streambuf,将fprintf实现为运行时格式解析器。IOstreams不需要运行时格式解析,这些都在编译时完成。因此,如果后端共享,则可以合理地期望iostreams在运行时更快。
是的,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;
}
当然,使用iostream而不是cstdio是荒谬的。至少在开发软件时(如果您已经使用c++而不是c,那么请充分利用它的优势,而不仅仅遭受它的缺点)。
但是在在线评测中,您不是在开发软件,而是创建一个程序,该程序应该能够在3秒内完成Microsoft软件需要60秒才能完成的任务!
因此,在这种情况下,黄金法则如下(当然,如果您使用Java会更麻烦):
cin
有很多开销,因为它在 scanf()
调用之上提供了一个抽象层。如果你正在编写 C++ 软件,就不应该使用 scanf()
而不是 cin
,因为这就是 cin
的作用。如果你想要性能,你可能不会在 C++ 中编写 I/O。std::istream
(通过I/O操作符或通过在istream
对象本身上设置标志)。另一方面,FILE*
对象没有这种状态,因此在这方面调用scanf
更加稳定。 - dreamlax