为什么使用std :: endl和ostringstream会影响输出速度? [英] Why does using std::endl with ostringstream affect output speed?

查看:755
本文介绍了为什么使用std :: endl和ostringstream会影响输出速度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算将文字打印到标准输出的各种方法之间的差异。我正在测试 cout printf ostringstream \\\
std :: endl 。我预期 std :: endl cout (和它的确)有区别,但我没想到它用 ostringstream 减慢输出。我认为使用 std :: endl 只会写一个 \\\
到流,它仍然只会被刷新一旦。这里发生了什么?这是我的所有代码:

I'm timing the difference between various ways to print text to standard output. I'm testing cout, printf, and ostringstream using both \n and std::endl. I expected std::endl to make a difference with cout (and it did), but I didn't expect it to slow down output with ostringstream. I thought using std::endl would just write a \n to the stream and it would still only get flushed once. What's going on here? Here's all my code:

// cout.cpp
#include <iostream>

using namespace std;

int main() {
  for (int i = 0; i < 10000000; i++) {
    cout << "Hello World!\n";
  }
  return 0;
}

// printf.cpp
#include <stdio.h>

int main() {
  for (int i = 0; i < 10000000; i++) {
    printf("Hello World!\n");
  }
  return 0;
}

// stream.cpp
#include <iostream>
#include <sstream>

using namespace std;

int main () {
  ostringstream ss;
  for (int i = 0; i < 10000000; i++) {
    ss << "stream" << endl;
  }
  cout << ss.str();
}

// streamn.cpp
#include <iostream>
#include <sstream>

using namespace std;

int main () {
  ostringstream ss;
  for (int i = 0; i < 10000000; i++) {
    ss << "stream\n";
  }
  cout << ss.str();
}

这是我的Makefile

And here's my Makefile

SHELL:=/bin/bash

all: cout.cpp printf.cpp
    g++ cout.cpp -o cout.out
    g++ printf.cpp -o printf.out
    g++ stream.cpp -o stream.out
    g++ streamn.cpp -o streamn.out
time:
    time ./cout.out > output.txt
    time ./printf.out > output.txt
    time ./stream.out > output.txt
    time ./streamn.out > output.txt

这是我运行 $ c>后跟 make time

time ./cout.out > output.txt

real    0m1.771s
user    0m0.616s
sys 0m0.148s
time ./printf.out > output.txt

real    0m2.411s
user    0m0.392s
sys 0m0.172s
time ./stream.out > output.txt

real    0m2.048s
user    0m0.632s
sys 0m0.220s
time ./streamn.out > output.txt

real    0m1.742s
user    0m0.404s
sys 0m0.200s

这些结果是一致的。

推荐答案

std :: endl 触发刷新流,这会减慢打印速度。请参见 http://en.cppreference.com/w/cpp/io/manip/endl

std::endl triggers a flush of the stream, which slows down printing a lot. See http://en.cppreference.com/w/cpp/io/manip/endl

除非你真的想要刷新流,否则建议不要使用 std :: endl 。如果这对你真的很重要,取决于你的用例。

It is often recommended to not use std::endl unless you really want the stream to be flushed. If this is really important to you, depends on your use case.

关于为什么 flush 在ostringstream(不会发生刷新):似乎需要一个实现来至少构造哨兵对象。那些需要检查 ostream tie 。对 pubsync 的调用应该能够优化。这是基于我对libcpp和libstdc ++的阅读。

Regarding why flush has a performance impact even on a ostringstream (where no flushing should happen): It seems that an implementation is required to at least construct the sentry objects. Those need to check good and tie of the ostream. The call to pubsync should be able to be optimized out. This is based on my reading of libcpp and libstdc++.

经过一些更多的阅读后,有趣的问题似乎是这样的:是一个 basic_ostringstream的实现: :flush 真的需要构造sentry对象吗?如果不是,这似乎是一个执行质量问题给我。但我实际上认为它需要,因为即使 basic_stringbug 也可以更改为 badbit 设置。

After some more reading the interesting question seems to be this: Is an implementation of basic_ostringstream::flush really required to construct the sentry object? If not, this seems like a "quality of implementation" issues to me. But I actually think it needs to because even a basic_stringbug can change to have its badbit set.

这篇关于为什么使用std :: endl和ostringstream会影响输出速度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆