在 C++ 程序中使用 scanf() 比使用 cin 快吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1042110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using scanf() in C++ programs is faster than using cin?
提问by zeroDivisible
I don't know if this is true, but when I was reading FAQ on one of the problem providing sites, I found something, that poke my attention:
我不知道这是否属实,但是当我在其中一个提供问题的网站上阅读常见问题解答时,我发现了一些引起我注意的东西:
Check your input/output methods. In C++, using cin and cout is too slow. Use these, and you will guarantee not being able to solve any problem with a decent amount of input or output. Use printf and scanf instead.
检查您的输入/输出方法。在 C++ 中,使用 cin 和 cout 太慢了。使用这些,您将保证无法通过大量输入或输出解决任何问题。请改用 printf 和 scanf。
Can someone please clarify this? Is really using scanf()in C++ programs faster than using cin >> something? If yes, that is it a good practice to use it in C++ programs? I thought that it was C specific, though I am just learning C++...
有人可以澄清一下吗?在 C++ 程序中使用scanf()真的比使用cin >> something快吗?如果是,在 C++ 程序中使用它是一个好习惯吗?我认为它是特定于 C 的,尽管我只是在学习 C++...
回答by nibot
Here's a quick test of a simple case: a program to read a list of numbers from standard input and XOR all of the numbers.
这是一个简单案例的快速测试:一个从标准输入读取数字列表并对所有数字进行异或的程序。
iostream version:
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 version:
扫描版本:
#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;
}
Results
结果
Using a third program, I generated a text file containing 33,280,276 random numbers. The execution times are:
使用第三个程序,我生成了一个包含 33,280,276 个随机数的文本文件。执行时间为:
iostream version: 24.3 seconds
scanf version: 6.4 seconds
Changing the compiler's optimization settings didn't seem to change the results much at all.
改变编译器的优化设置似乎根本没有改变结果。
Thus: there really is a speed difference.
因此:确实存在速度差异。
EDIT:User clyfish points out belowthat the speed difference is largely due to the iostream I/O functions maintaining synchronization with the C I/O functions. We can turn this off with a call to std::ios::sync_with_stdio(false);
:
编辑:用户 clyfish在下面指出速度差异主要是由于 iostream I/O 函数与 CI/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;
}
New results:
新结果:
iostream version: 21.9 seconds
scanf version: 6.8 seconds
iostream with sync_with_stdio(false): 5.5 seconds
C++ iostream wins!It turns out that this internal syncing / flushing is what normally slows down iostream i/o. If we're not mixing stdio and iostream, we can turn it off, and then iostream is fastest.
C++ iostream 获胜!事实证明,这种内部同步/刷新通常会减慢 iostream i/o。如果我们不混合 stdio 和 iostream,我们可以将其关闭,然后 iostream 是最快的。
The code: https://gist.github.com/3845568
回答by clyfish
http://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
http://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
Performance of cin
/cout
can be slow because they need to keep themselves in sync with the underlying C library. This is essential if both C IO and C++ IO is going to be used.
cin
/ 的性能cout
可能很慢,因为它们需要与底层 C 库保持同步。如果要同时使用 C IO 和 C++ IO,这是必不可少的。
However, if you only going to use C++ IO, then simply use the below line before any IO operations.
但是,如果您只打算使用 C++ IO,那么只需在任何 IO 操作之前使用以下行。
std::ios::sync_with_stdio(false);
For more info on this, look at the corresponding libstdc++ docs.
有关这方面的更多信息,请查看相应的libstdc++ 文档。
回答by 1800 INFORMATION
Probably scanf is somewhat faster than using streams. Although streams provide a lot of type safety, and do not have to parse format strings at runtime, it usually has an advantage of not requiring excessive memory allocations (this depends on your compiler and runtime). That said, unless performance is your only end goal and you are in the critical path then you should really favour the safer (slower) methods.
scanf 可能比使用流要快一些。尽管流提供了很多类型安全性,并且不必在运行时解析格式字符串,但它通常具有不需要过多内存分配的优点(这取决于您的编译器和运行时)。也就是说,除非性能是您唯一的最终目标并且您处于关键路径中,否则您应该真正喜欢更安全(更慢)的方法。
There is a very delicious article written here by Herb Sutter "The String Formatters of Manor Farm" who goes into a lot of detail of the performance of string formatters like sscanf
and lexical_cast
and what kind of things were making them run slowly or quickly. This is kind of analogous, probably to the kind of things that would affect performance between C style IO and C++ style. The main difference with the formatters tended to be the type safety and the number of memory allocations.
这里是香草萨特“这里写的很美味的文章庄园农场的字符串格式化程序谁进入了很多字符串格式化,比如性能的细节”sscanf
和lexical_cast
什么样的事情让他们慢慢地或快速运行。这有点类似于,可能会影响 C 风格 IO 和 C++ 风格之间的性能。与格式化程序的主要区别往往是类型安全和内存分配的数量。
回答by Bogatyr
I just spent an evening working on a problem on UVa Online (Factovisors, a very interesting problem, check it out):
我刚刚花了一个晚上在 UVa Online 上研究一个问题(Factovisors,一个非常有趣的问题,看看):
I was getting TLE (time limit exceeded) on my submissions. On these problem solving online judge sites, you have about a 2-3 second time limit to handle potentially thousands of test cases used to evaluate your solution. For computationally intensive problems like this one, every microsecond counts.
我在提交时收到了 TLE(超出时间限制)。在这些解决问题的在线裁判网站上,您有大约 2-3 秒的时间来处理可能用于评估您的解决方案的数千个测试用例。对于像这样的计算密集型问题,每一微秒都很重要。
I was using the suggested algorithm (read about in the discussion forums for the site), but was still getting TLEs.
我正在使用建议的算法(在该站点的讨论论坛中阅读),但仍然得到 TLE。
I changed just "cin >> n >> m" to "scanf( "%d %d", &n, &m )" and the few tiny "couts" to "printfs", and my TLE turned into "Accepted"!
我只将“cin >> n >> m”改为“scanf(“%d %d”, &n, &m )”,将几个小的“couts”改为“printfs”,我的TLE变成了“Accepted”!
So, yes, it can make a big difference, especially when time limits are short.
所以,是的,它可以产生很大的不同,尤其是在时间限制很短的情况下。
回答by xtofl
If you care about both performance and string formatting, do take a look at Matthew Wilson's FastFormatlibrary.
如果您关心性能和字符串格式,请查看Matthew Wilson 的 FastFormat库。
edit -- link to accu publication on that library: http://accu.org/index.php/journals/1539
编辑 - 链接到该图书馆的 accu 出版物:http: //accu.org/index.php/journals/1539
回答by MSalters
There are stdio implementations (libio) which implements FILE* as a C++ streambuf, and fprintf as a runtime format parser. IOstreams don't need runtime format parsing, that's all done at compile time. So, with the backends shared, it's reasonable to expect that iostreams is faster at runtime.
有 stdio 实现 ( libio) 将 FILE* 实现为 C++ streambuf,将 fprintf 实现为运行时格式解析器。IOstreams 不需要运行时格式解析,这都是在编译时完成的。因此,在后端共享的情况下,期望 iostreams 在运行时更快是合理的。
回答by pedro.lupin
Yes iostream is slower than cstdio.
Yes you probably shouldn't use cstdio if you're developing in C++.
Having said that, there are even faster ways to get I/O than scanf if you don't care about formatting, type safety, blah, blah, blah...
是的 iostream 比 cstdio 慢。
是的,如果您使用 C++ 进行开发,您可能不应该使用 cstdio。
话虽如此,如果您不关心格式,类型安全,等等,等等,等等,还有比 scanf 更快的获取 I/O 的方法...
For instance this is a custom routine to get a number from STDIN:
例如,这是一个从 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;
}
回答by Prasoon Varshney
The statements cin
and cout
in general use seem to be slower than scanf
and printf
in C++, but actually they are FASTER!
语句cin
和cout
一般使用似乎比C++ 中的scanf
和慢printf
,但实际上它们更快!
The thing is: In C++, whenever you use cin
and cout
, a synchronization process takes place by default that makes sure that if you use both scanf
and cin
in your program, then they both work in sync with each other. This sync process takes time. Hence cin
and cout
APPEAR to be slower.
问题是:在 C++ 中,每当您使用cin
and 时cout
,默认情况下都会发生同步过程,以确保如果您在程序中同时使用scanf
和cin
,那么它们会彼此同步工作。这个同步过程需要时间。因此cin
,cout
看起来更慢。
However, if the synchronization process is set to not occur, cin
is faster than scanf
.
但是,如果同步过程设置为不发生,cin
则比 快scanf
。
To skip the sync process, include the following code snippet in your program right in the beginning of main()
:
要跳过同步过程,请在程序的开头包含以下代码片段main()
:
std::ios::sync_with_stdio(false);
Visit this sitefor more information.
访问此站点以获取更多信息。
回答by hexec
#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;
}
There's a bug at the end of the file, but this C code is dramatically faster than the faster C++ version.
文件末尾有一个错误,但此 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
The original C++ took 30sec the C code took 2sec.
原来的 C++ 用了 30 秒,C 代码用了 2 秒。
回答by dreamlax
The problem is that cin
has a lot of overhead involved because it gives you an abstraction layer above scanf()
calls. You shouldn't use scanf()
over cin
if you are writing C++ software because that is want cin
is for. If you want performance, you probably wouldn't be writing I/O in C++ anyway.
问题是cin
涉及很多开销,因为它为您提供了一个高于scanf()
调用的抽象层。如果您正在编写 C++ 软件,则不应使用scanf()
over cin
,因为那是需要cin
的。如果您想要性能,您可能无论如何都不会用 C++ 编写 I/O。