Efficiency of C vs C++ streams

Feb 18, 2014 at 1:06pm
For the common std libraries that handle data in C/C++ I was wondering which of these is A) the quickest and B) uses less resources/processing.

ostream << VS printf()
istream >> VS scanf()
ofstream << VS fprintf()
ifstream >> VS fscanf()

And if possible I'd like to know how much better/worse each is or if there's specific cases/reasons why this is so. It's nothing really important, just some background knowledge...

Oh and since I'm here, why's printf/scanf/etc considered "unsafe"? Why is s_printf (or whatever it is) needed?


Thanks in advance
Feb 18, 2014 at 1:54pm
SatsumaBenji wrote:
Oh and since I'm here, why's printf/scanf/etc considered "unsafe"?

By using scanf() in your program you allow the user to cause buffer overflows.
The example below shows how the user can overwrite things he shouldn't.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(void)
{
    char name_color[2][6] = {"Teddy", "Green"};

    printf("Reading name (but not color): ");
    scanf("%s", name_color[0]);
    printf("New name is: %s, color is %s.\n",
        name_color[0], name_color[1]);
}
C:\learn.c>buffer_overflow.exe
Reading name (but not color): Hello!World
New name is: Hello!World, color is World.


With printf() the possible danger lies in letting the user give a custom format string (but this is easily prevented by being careful).

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main(void)
{
    char fmt[10];

    gets(fmt); // also unsafe, can be overflowed

    printf(fmt);
    // don't do this, the user should not be trusted
    // to give a format string
}
C:\learn.c>fmt.exe
Hello %d!
Hello 4201072!


As for the efficiency of C I/O vs C++ I/O, theoretically the bottleneck is the hardware, so they should both be as fast. That said, a lot of code needs to be parsed to compile a program using C++ streams.

As others would say: actually measure performance and ignore talk about performance.
Feb 18, 2014 at 2:21pm
For the common std libraries that handle data in C/C++ I was wondering which of these is A) the quickest
We looked at this, just inmemory formatting. Interesting results.
http://www.cplusplus.com/forum/general/74026/
Feb 18, 2014 at 3:48pm
@Catfish C++ I/O allows overflows too:

1
2
3
4
// error:
// scanf("%s", name_color[0]);
// fix:
scanf("%5s", name_color[0]);


1
2
3
4
// error:
// std::cin >> name_color[0];
// fix:
std::cin >> setw(6) >> name_color[0];




(gets has no way to limit the input, which is why it was removed from the languages)
Feb 18, 2014 at 6:59pm
Thanks Cubbi, it never occurred to me that length specifiers can also be used for input.
I'd have a question of my own, how come in the first snippet you used 5, yet in the second, 6?
Feb 18, 2014 at 7:06pm
%Ns/%N[ extract up to N chars from the stream and write what they extracted plus null char
operator>>(istream&, char*) extracts up to width-1 chars and writes what it extracted plus null
Feb 18, 2014 at 9:42pm
Thanks for the answers guys.

Whenever you see a C tutorial for IO it's always quite outdated or tries to be very traditional and not many take count for newer methods used for programming safety and other things.

@kbw, just to check because I found them results a little difficult to decipher :)...
C style IO (print/scan) is quicker than streams in most cases but if you have one streams have increased performance for multi-threading and better safety?
Feb 19, 2014 at 2:01pm
The conclusion was the C routines were faster on GCC, even though the C++ routines ought to be faster.

Also, stream construction was very expensive on GCC and much slower in an multi-threaded environment. I think I quoted 18 times slower than in a single threaded environment, but I don't remember how I concluded that.

Even accounting for stream construction, the C I/O was faster.
Feb 19, 2014 at 2:10pm
Note that neither C++ streams nor C streams are actually designed for speed/

If you're looking for fast parsing/formatting, use parser generators/ (boost.spirit/boost.karma are a good baseline for C++)

If you're looking for fast bulk I/O, then they are generally equivalent unless misused (e.g. both fread() and istream::read() generally make the same POSIX read(2) or equivalent), but there may be system-specific API that offer better throughput.
Feb 19, 2014 at 7:14pm
Well I'm not particularly looking for a faster IO method, as I said I'm just doing a little background knowledge gathering...

Anyways thanks guys, very helpful on both answers.
Topic archived. No new replies allowed.