Using Scanf() in C++ Programs Is Faster Than Using Cin

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



Leave a reply



Submit