Why does endl get used as a synonym for "\n" even though it incurs significant performance penalties?
This program:
#include <iostream>
#include <cstdlib>
#include <string>
int main(int argc, const char *argv[])
{
using ::std::cerr;
using ::std::cout;
using ::std::endl;
if (argc < 2 || argc > 3) {
cerr << "Usage: " << argv[0] << " [<count>] <message>\n";
return 1;
}
unsigned long count = 10000;
if (argc > 2) {
char *endptr = 0;
count = ::std::strtoul(argv[1], &endptr, 10);
if ((argv[1][0] == '\0') || (*endptr != '\0')) {
cerr << "Usage: " << argv[0] << " [<count>] <message>\n";
return 1;
}
}
const ::std::string msg((argc < 3) ? argv[1] : argv[2]);
for (unsigned long i = 0; i < count; ++i) {
cout << i << ": " << msg << '\n';
}
return 0;
}
when timed like so:
$ time ./joe 10000000 fred >/dev/null
real 0m15.410s
user 0m10.551s
sys 0m0.166s
takes 15.4 seconds of real time to execute. Replace the output line with this: cout << i << ": " << msg << endl;
开发者_开发百科 and you end up with something like this:
$ time ./joe 10000000 fred >/dev/null
real 0m39.115s
user 0m16.482s
sys 0m15.803s
As you can see, the time to run more than doubles, and the program goes from spending minimal time in the OS to spending nearly half of it's time in the OS.
Both versions of the program have identical output, and are guaranteed by the standard to have identical output on every platform.
Given this, why do people persist in using endl
as a synonym for '\n'?
Edit: In case it isn't obvious, this question is intended to be a leading question and is here for instructional purposes. I know why the performance penalty exists.
I'm not certain. Inserting std::endl
into the output stream is defined as being equivalent to inserting .widen('\n')
and then calling flush()
and yet many programmers persist in using std::endl
even when there is no cause to flush, for example they go on to immediately output something else.
My assumption is that it comes from an incorrect belief that it is somehow a more portable because it doesn't explicitly use a specific newline character. This is incorrect as \n
must always be mapped to the system's correct newline sequence for non-binary files by the stream library.
Afaik, endl also flushes the stream, which may be the cause of the performance penalty.
Not everyone cares so much about performance. For some applications, guaranteeing the stream is flushed is much more important.
Edit: Also, I find endl
easier to type than '\n'
:-)
I tend to use endl with on stringstreams as it makes it easy to spot missing linebreaks.
My guess is that instructional texts use std::endl
with the belief that it's simpler and less confusing for beginners, and afterward people got accustomed to using it.
The real question is, why did the compiler make such a dogs breakfast of compiling the endl version? If they're guaranteed to have the same semantics, then they should also have the same runtime.
Edit: obviously, I wasn't aware that endl flushed the stream... that's what you get for not looking it up.
精彩评论