Cin Cout vs Scanf Printf

当输入量很大时,常规的有竞争力的程序员面临着共同的挑战,从stdin读取这样的输入可能会成为一个瓶颈。这种问题伴随着“警告:大量I/O数据”。

null

让我们创建一个虚拟输入文件,其中包含一个16字节的行,后跟一个换行符,有1000000行这样的行,制作一个17MB的文件就足够了。

// Creating a dummy file of size 17 MB to compare 
// performance of scanf() and cin()
$ yes 1111111111111111 | head -1000000 > tmp/dummy

让我们比较一下使用scanf()和cin从stdin读取文件所需的时间(使用重定向将文件从磁盘读取到stdin)。

// Filename : cin_test.cc to test the
// We redirect above created temp file
// of 17 MB to stdin when this program
// is run.
#include<iostream>
using namespace std;
int main()
{
char buffer[256];
while (cin >> buffer)
{
}
return 0;
}


当虚拟文件被重定向到stdin时,上述程序的输出。

$ g++ cin_test.cc –o cin_test
$ time ./cin_test < /tmp/dummy
real	 0m2.162s
user	 0m1.696s
sys	 0m0.332s

// Filename : scanf_test.c to see
// performance of scanf()
// We redirect above created temp file
// of 17 MB to stdin when this program
// is run.
#include<cstdlib>
#include<cstdio>
int main()
{
char buffer[256];
while ( scanf ( "%s" , buffer) != EOF)
{
}
return 0;
}


当虚拟文件被重定向到stdin时,上述程序的输出。

$ g++ scanf_test.cc –o scanf_test
$ time ./scanf_test < /tmp/dummy
real	 0m0.426s
user	 0m0.248s
sys	 0m0.084s

以上结果与我们的观察结果一致。

为什么scanf比cin更快? 从更高的层面来看,它们都是包装纸 读() 系统调用,只是语法糖。唯一明显的区别是 scanf() 必须显式声明输入类型,而 cin 使用模板重载重定向操作。这似乎不足以成为性能达到5倍的理由。

事实证明 利用 斯特迪奥 的缓冲系统。所以 cin 浪费时间与底层C库的同步 斯特迪奥 缓冲区,以便调用 scanf() cin 可以交错。

好消息是libstdc++提供了一个选项来关闭所有数据的同步 标准流及其相应的标准C流使用

std::ios::sync_with_stdio(false);

cin 变得比 scanf() 本来应该如此。

一篇关于 竞争性编程中的快速输入输出

// Filename : cin_test_2.cc to see
// performance of cin() with stdio syc
// disabled using sync_with_stdio(false).
#include<iostream>
using namespace std;
int main()
{
char buffer[256];
ios_base::sync_with_stdio( false );
while (cin >> buffer)
{
}
return 0;
}


运行程序:

$ g++ cin_test_2.cc –o cin_test_2
$ time./cin_test_2 </tmp/dummy
real    0m0.380s
user   0m0.240s
sys    0m0.028s 
  • 就像所有事情一样,这里有一个警告。在关闭同步的情况下,使用 cin scanf() 一起将导致一个未定义的混乱。
  • 关闭同步后,上述结果表明 cin 比之前快8-10% scanf() .这可能是因为 scanf() 在运行时解释格式参数,并使用可变数量的参数,而 cin 在编译时执行此操作。

现在想知道,这能以多快的速度完成?

// Redirecting contents of dummy file to null
// device (a special device that discards the
// information written to it) using command line.
$time cat /tmp/dummy > /dev/null
real   0m0.185s
user   0m0.000s
sys    0m0.092s

哇!这太快了!!!

本文由 阿尤什·戈维尔 .如果你喜欢GeekSforgek,并且想贡献自己的力量,你也可以写一篇文章,并将文章邮寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享