cin/cout-printf/scanf

hi, i'd like to ask about differences between [cin, cout] and [printf, scanf]
i'm just kind of confused of these..XD
cout & cin are part of the iostream interface for input and output. They are an ostream object and an istream object, respectively. They use the overloaded << operator to output any object, based on its type and the various flags set by manipulators.
printf and scanf are part of the stdio.h interface also known as cstdio. They are variable-argument functions, which use a format specification to tell them what the types of their arguments are. Some find the iostream interface easier, and it is safer and expandable. However, these advantages come at a small performance penalty. printf and scanf on the other hand are a bit faster, but are unsafe, and some find them harder to use.
Last edited on
About printf being faster than cout - it is implementation dependant. Here, a naive benchmark:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <sstream>
#include <cstdio>
#include <ctime>

int main(int argc, char* argv[]) {
    int loops = 1000000;
    if (argc > 1) {
        std::stringstream ss;
        ss << argv[1];
        ss >> loops;
    }
    
    std::clock_t start[2];
    double diff[2];
    
    // std::cout 
    start[0] = std::clock();
    for (int i = 0; i < loops; i++)
        std::cout << "a";
    diff[0] = (std::clock() - start[0]) / static_cast<double>(CLOCKS_PER_SEC);

    // printf
    start[1] = std::clock();
    for (int i = 0; i < loops; i++)
        std::printf("a");
    diff[1] = (std::clock() - start[1]) / static_cast<double>(CLOCKS_PER_SEC);

    std::cerr << "cout:   " << diff[0] << '\n'
            << "printf: " << diff[1] << '\n';
            
    return 0;
}
And the result here is:
1
2
3
$ ./test 5000000 > file
cout:   0.984
printf: 0.641


Now, consider these changes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <sstream>
#include <cstdio>
#include <ctime>

int main(int argc, char* argv[]) {
    std::cout.sync_with_stdio(false);
    
    int loops = 1000000;
    if (argc > 1) {
        std::stringstream ss;
        ss << argv[1];
        ss >> loops;
    }
    
    std::clock_t start[2];
    double diff[2];
    
    // cout
    start[0] = std::clock();
    for (int i = 0; i < loops; i++)
        std::cout << "a"; // fast enough to outperform printf() but...
//        std::cout.rdbuf()->sputn("a", 1); // is even faster.
    diff[0] = (std::clock() - start[0]) / static_cast<double>(CLOCKS_PER_SEC);

    // printf
    start[1] = std::clock();
    for (int i = 0; i < loops; i++)
        std::printf("a");
    diff[1] = (std::clock() - start[1]) / static_cast<double>(CLOCKS_PER_SEC);

    std::cerr << "cout:   " << diff[0] << '\n'
            << "printf: " << diff[1] << '\n';
            
    return 0;
}

And this code gives me:
1
2
3
$ ./test 5000000 > file
cout:   0.343
printf: 0.672

if you comment the std::cout line and uncomment the following one:std::cout.rdbuf()->sputn("a", 1);will most likely make it even faster:
1
2
3
$ ./test 5000000 > file
cout:   0.234
printf: 0.641

So, the speed is there, if you need it. I remember cout being much slower in the past though. Not that it would really matter most of the time. ;)

Tests compiled with MinGW's g++ 4.5.2
g++.exe -pedantic -Wall -Wextra -Werror -Wunused -Wundef -c -O3 -Werror -s -MMD -MP -MF
on Windows XP, Core 2 Duo E4300 2x1.8GHz
Last edited on
You didn't measure the startup time. Cin and cout have penalties for startup. In addition, you didn't measure for different types of operands. When outputting an entire object, say a spaceship, a single printf call like:
printf("%s: %f %f %f %f %f %f %d",s.name,s.x,s.y,s.z,s.dx,s.dy,s.dz,s.fuel);
is about twice as fast as cout with 8 separate operator overload function calls:
cout << s.name << s.x << s.y << s.z << s.dx << s.dy << s.dz << s.fuel;
I've run and posted extensive tests in another thread showing the overhead. If you like I will give you a link.
I'd love to see that, sure. :)
edit: Still, if you take the creating of the string outside the loop, with lets say std::stringstream and sprintf(), and output just the strings, cout will obviously still beat printf.

I tested what you pasted, and added spaces to the cout line, just to make it identical (even more function calls) and I didn't get 2:1 printf win, more or less 4.1:2.7 - printf still is faster, considerably.

In real world though, the object would probably provide its own printing function (or << overload) that should usually implement sort of caching of the string representation, if the object didn't change from one printing to another. (That is, if one object would be assumed to be printed this way a lot in its lifetime)
In that case cout would be faster if we would print the objects that are rarely ever modified, and a slkightly slower if we would print lots of barely-new/modified objects. It would depend on how often they would be printed and modified.

Bah, I hope I didn't start cout/printf flame all over again? In the end it's not really speed that counts, but plenty of other things too. :)
Last edited on
Actually, in this thread I conclusively proved that printf > iostream > istringstream. On this particular post I demonstrated that even with optimization, cout and cin are more than twice as slow as scanf and printf.
http://www.cplusplus.com/forum/general/33845/page4.html#msg183520
As for istringstream, read the thread. It was started when someone noticed that istringstream is as slow as a turtle in molasses.
Last edited on
Topic archived. No new replies allowed.