简体   繁体   English

为什么endl被用作“\\ n”的同义词,即使它会导致严重的性能损失?

[英]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. 执行需要15.4秒的实时时间。 Replace the output line with this: cout << i << ": " << msg << endl; 用这个替换输出行: 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'? 鉴于此,为什么人们坚持使用endl作为'\\n'?的同义词'\\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. std::endl插入输出流定义为等同于插入.widen('\\n')然后调用flush() ,然而许多程序员仍然坚持使用std::endl即使没有原因要刷新,例如,他们继续立即输出其他东西。

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. 这是不正确的,因为\\n必须始终映射到流库的非二进制文件的系统正确的换行序列。

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' :-) 编辑:另外,我发现endl'\\n'更容易输入:-)

Afaik,endl也会刷新流,这可能是性能损失的原因。

我倾向于在字符串流上使用endl,因为它可以很容易地发现丢失的换行符。

我的猜测是教学文本使用std::endl ,相信它对于初学者来说更简单,更容易混淆,之后人们习惯于使用它。

The real question is, why did the compiler make such a dogs breakfast of compiling the endl version? 真正的问题是,为什么编译器会编译这样的狗早餐编译endl版本? 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. 编辑:很明显,我不知道endl刷新了流...这就是你没有查找它的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM