Using scanf() in C++ programs is faster than using cin?
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:
#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:
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 below that 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);
:
#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.
The code: https://gist.github.com/3845568
Why does printf executes faster than cout in C++?Also scanf is slower than cin,why?
By default, cin/cout waste time synchronizing themselves with the C library’s stdio buffers, so that you can freely intermix calls to scanf/printf with operations on cin/cout.
Turn this off with
std::ios_base::sync_with_stdio(false);
Also many C++ tutorials tell you to write cout << endl
instead of cout << '\n'
. But endl
is actually slower because it forces a flush, which is usually unnecessary. (You’d need to flush if you were writing, say, an interactive progress bar, but not when writing a million lines of data.) Write '\n'
instead of endl
.
Also as C++ is object-oriented , cin
and cout
are objects and hence the overall time is increased due to object binding.
So, a simple one liner, std::ios_base::sync_with_stdio(false);
could make cin/cout
faster than printf/scanf
.
Hope this helps you
why is cin/cout slower than scanf/ printf
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);
By default standard C++ streams are synchronized to the standard C stream after each input/output operation.
Once synchronization is turned off, the C++ standard streams are allowed to buffer their I/O independently, you can try and see the time taken will be almost similar (possibly lesser than scanf)
printf/scanf usage and difference from iostream and cout/cin diffferences, when to use which?
Regular competitive programmers face common challenge when input is large and the task of reading such an input from stdin might prove to be a bottleneck. Such problem is accompanied with “Warning: large I/O data”.
cin/cout is faster than scanf/printf, key differnce among these.
Why is scanf faster than cin?
On a high level both of them are wrappers over theread() system call, just syntactic sugar. The only visible difference is that scanf() has to explicitly declare the input type, whereas cin has the redirection operation overloaded using templates. This does not seem like a good enough reason for a performance hit of 5x.
It turns out that iostream makes use of stdio‘s buffering system. So, cin wastes time synchronizing itself with the underlying C-library’s stdio buffer, so that calls to bothscanf()and cin can be interleaved.
The good thing is that libstdc++ provides an option to turn off synchronization of all the iostream standard streams with their corresponding standard C streams using
std::ios::sync_with_stdio(false);
same with cout and printf.
but in simple words, cin, cout uses extraction and insertion in c++ which are basically overloaded, hence another factor of slow speed.
I hope this answer your question of why one is preferred over another and they are basically the way to input data, and internally cin, cout is written using c stdio buffer library.
Why do printf scanf is slower than cout cin in this case?
No, cin
and cout
aren't significantly different from using printf
/scanf
. However, endl
will call ofstream::flush()
, which would be the same thing as printf("%d\n", cost); fflush(stdout);
, and I expect if you did that, it would run slower there too.
Also, mixing cin
with scanf
or similar will add more time, because the code has to "sync" the two I/O streams all the time. I would suggest you rewrite your scanf
input as:
while(scanf("%d %d %d %d", &N, &B, &H, &W) != EOF){
int cost = inf;
// remove scanf and cin.eof() line here
...
}
To prove my point about (at least output):
#include <iostream>
#include <cstdio>
using namespace std;
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
int main(int argc, char **argv)
{
unsigned long long t = rdtsc();
if (argc > 1)
{
for(int i = 0; i < 1000; i++)
{
printf("%d", i);
}
}
else
{
for(int i = 0; i < 1000; i++)
{
cout << i << "\n";
}
}
t = rdtsc() - t;
cerr << "Time: " << t << endl;
}
The output from this, when running with no arguments (argc == 1
) and running with an argument (argc == 2
) is:
$ ./a.out > foo.txt
Time: 1672894
$ ./a.out 1 > foo.txt
Time: 1513620
Approximately 10% difference in favour of printf
. However, there is quite a bit of variation in my system when I run any benchmark, so that should be taken with a pinch of salt. Note that using endl
instead of "/n"
makes a significant difference!
For cin
vs. scanf
, there is a little more difference to the disadvantage of scanf
:
#include <iostream>
#include <cstdio>
using namespace std;
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
int main(int argc, char **argv)
{
unsigned long long t = rdtsc();
if (argc > 1)
{
for(int i = 0; i < 1000; i++)
{
int tmp;
scanf("%d", &tmp);
}
}
else
{
for(int i = 0; i < 1000; i++)
{
int tmp;
cin >> tmp;
}
}
t = rdtsc() - t;
cerr << "Time: " << t << endl;
}
$ ./a.out < foo.txt
Time: 1990454
$ ./a.out 1 < foo.txt
Time: 4804226
As you can see, scanf
is nearly 2.5 times slower... However, I have seen other cases where it's not such a big difference. I'm not entirely sure why there is such a big difference here.
In summary, there are difference, but I do believe the answer by James Kanze is closer to explaining what is going on - the code simply fails to complete because cin.eof()
does not get set by scanf
.
using scanf and printf makes the program infinite loop but by replacing with cin and cout works ok
When dealing with C you should always check return values of runtime functions, it is the best way to avoid getting errors like the one you have.
scanf returns the number of items that it managed to parse or 0 if it failed.
personally i prefer to use fgets() to read from the stdin and then sscanf to parse the buffer, that way you have (IMHO) a better control of what comes into the program as opposed to obscure scanf formatting. it is easy to do mistakes with scanf because one tends to forget that all input is buffered and scanf reads from that buffer.
E.g. (ocular compiled only)
int click = 0;
int test = 0;
char buffer[128];
char vote = 0;
do
{
if ( fgets(buffer,sizeof(buffer),stdin) != NULL)
{
// read number of tests
if (sscanf(buffer, "%d", &test) == 1)
{
for(int i=0; i < test; ++i)
{
if (fgets(buffer, sizeof(buffer), stdin) != NULL)
{
if (sscanf( buffer, "%c %d", &vote, &click) == 2)
{
printf( "%c %d hi \n", vote, click );
}
else
{
fprintf(stderr, "Invalid format encountered\n");
}
}
}
}
}
}
while (test);
Disadvantages of turning off cin synchronization with C scanf
If you use both sets of I/O functions (header <cstdio>
or <stdio.h>
and also <iostream>
) on the same stream (e.g. the stdin
stream is associated with both scanf
and cin
), then you'd better leave them synchronized.
If any one stream only uses one I/O family you can turn off synchronization (you can still use fscanf
with a particular file and cin
with stdin
for example, as long as separate streams are involved).
When to use printf/scanf vs cout/cin?
There are a few oddities where char*
is needed. You can bridge the gap by using the .c_str()
method of a std::string
to get one.
For the most part, the C subset of C++ is compatible. Exactly how it isn't compatible is not likely to matter for the most part:
http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B
If you're compiling snippets of C code under a C++ compiler, be sure to change it to use the "c" lib format in your includes...for example #include <cstdio>
instead of #include <stdio.h>
Is it bad practice to use a C header instead of its C++ equivalent in C++ (e.g. stdio.h instead of cstdio)?
For a fairly reasoned argument from Bjarne himself on why to avoid scanf, check out the beginning of this paper:
http://www.stroustrup.com/new_learning.pdf
There are a lot of benefits to using iostreams instead of printf as well:
'printf' vs. 'cout' in C++
Related Topics
What Is the Worst Real-World Macros/Pre-Processor Abuse You'Ve Ever Come Across
Initializing Fields in Constructor - Initializer List VS Constructor Body
Std::Thread Pass by Reference Calls Copy Constructor
Sfinae to Check For Inherited Member Functions
Multiple Definition in Header File
Is the 'Override' Keyword Just a Check For a Overridden Virtual Method
How to Implement Serialization in C++
How to Include Openssl in Visual Studio
Error Lnk2005, Already Defined
Do Unused Functions Get Optimized Out
What Techniques Can Be Used to Speed Up C++ Compilation Times
C++ Alignment When Printing Cout ≪≪
Strict Aliasing Rule and 'Char *' Pointers
What Is a Simple Example of Floating Point/Rounding Error
How to Code a Modulo (%) Operator in C/C++/Obj-C That Handles Negative Numbers
Does Mingw-W64 Support Std::Thread Out of the Box When Using the Win32 Threading Model