为什么使用std :: endl和ostringstream会影响输出速度? [英] Why does using std::endl with ostringstream affect output speed?
问题描述
我打算将文字打印到标准输出的各种方法之间的差异。我正在测试 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屋!