问题描述
在执行一些测试后,我注意到 printf
比 cout
快得多.我知道它依赖于实现,但在我的 Linux 机器上 printf
快 8 倍.所以我的想法是混合两种打印方法:我想使用 cout
进行简单的打印,我计划使用 printf
来产生巨大的输出(通常在循环中).我认为只要在切换到其他方法之前不要忘记刷新就可以安全:
After performing some tests I noticed that printf
is much faster than cout
. I know that it's implementation dependent, but on my Linux box printf
is 8x faster. So my idea is to mix the two printing methods: I want to use cout
for simple prints, and I plan to use printf
for producing huge outputs (typically in a loop). I think it's safe to do as long as I don't forget to flush before switching to the other method:
cout << "Hello" << endl;
cout.flush();
for (int i=0; i<1000000; ++i) {
printf("World!
");
}
fflush(stdout);
cout << "last line" << endl;
cout << flush;
这样可以吗?
更新:感谢所有宝贵的反馈.答案摘要:如果您想避免棘手的解决方案,只需坚持使用 cout
但不要使用 endl
因为它会隐式刷新缓冲区(减慢进程).使用 "
"
代替.如果你产生大输出,这会很有趣.
Update: Thanks for all the precious feedbacks. Summary of the answers: if you want to avoid tricky solutions, simply stick with cout
but don't use endl
since it flushes the buffer implicitly (slowing the process down). Use "
"
instead. It can be interesting if you produce large outputs.
推荐答案
直接的回答是,是的,没关系.
The direct answer is that yes, that's okay.
很多人就如何提高速度提出了各种想法,但似乎对哪种方法最有效存在相当多的分歧.我决定编写一个快速测试程序,以至少了解哪些技术做了什么.
A lot of people have thrown around various ideas of how to improve speed, but there seems to be quite a bit of disagreement over which is most effective. I decided to write a quick test program to get at least some idea of which techniques did what.
#include <iostream>
#include <string>
#include <sstream>
#include <time.h>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <stdio.h>
char fmt[] = "%s
";
static const int count = 3000000;
static char const *const string = "This is a string.";
static std::string s = std::string(string) + "
";
void show_time(void (*f)(), char const *caption) {
clock_t start = clock();
f();
clock_t ticks = clock()-start;
std::cerr << std::setw(30) << caption
<< ": "
<< (double)ticks/CLOCKS_PER_SEC << "
";
}
void use_printf() {
for (int i=0; i<count; i++)
printf(fmt, string);
}
void use_puts() {
for (int i=0; i<count; i++)
puts(string);
}
void use_cout() {
for (int i=0; i<count; i++)
std::cout << string << "
";
}
void use_cout_unsync() {
std::cout.sync_with_stdio(false);
for (int i=0; i<count; i++)
std::cout << string << "
";
std::cout.sync_with_stdio(true);
}
void use_stringstream() {
std::stringstream temp;
for (int i=0; i<count; i++)
temp << string << "
";
std::cout << temp.str();
}
void use_endl() {
for (int i=0; i<count; i++)
std::cout << string << std::endl;
}
void use_fill_n() {
std::fill_n(std::ostream_iterator<char const *>(std::cout, "
"), count, string);
}
void use_write() {
for (int i = 0; i < count; i++)
std::cout.write(s.data(), s.size());
}
int main() {
show_time(use_printf, "Time using printf");
show_time(use_puts, "Time using puts");
show_time(use_cout, "Time using cout (synced)");
show_time(use_cout_unsync, "Time using cout (un-synced)");
show_time(use_stringstream, "Time using stringstream");
show_time(use_endl, "Time using endl");
show_time(use_fill_n, "Time using fill_n");
show_time(use_write, "Time using write");
return 0;
}
在使用 VC++ 2013(x86 和 x64 版本)编译后,我在 Windows 上运行了它.一次运行的输出(输出重定向到磁盘文件)如下所示:
I ran this on Windows after compiling with VC++ 2013 (both x86 and x64 versions). Output from one run (with output redirected to a disk file) looked like this:
Time using printf: 0.953
Time using puts: 0.567
Time using cout (synced): 0.736
Time using cout (un-synced): 0.714
Time using stringstream: 0.725
Time using endl: 20.097
Time using fill_n: 0.749
Time using write: 0.499
正如预期的那样,结果各不相同,但我觉得有几点很有趣:
As expected, results vary, but there are a few points I found interesting:
- 在写入 NUL 设备时,printf/puts 比 cout 快得多
- 但是 cout 在写入真实文件时保持得很好
- 在我的测试中,fill_n 与其他任何东西一样快
我最近编辑了代码以强制调用printf
.Anders Kaseorg 很友好地指出——g++
识别特定序列 printf("%s
", foo);
等价于 puts(foo);
,并相应地生成代码(即生成代码来调用 puts
而不是 printf
).将格式字符串移动到全局数组,并将其作为格式字符串传递会产生相同的输出,但强制它通过 printf
而不是 puts
产生.当然,他们也有可能在某一天对此进行优化,但至少现在 (g++ 5.1) 使用 g++ -O3 -S
进行的测试确认它实际上正在调用 printf
(前面的代码编译为对 puts
的调用).
I've recently edited the code to force a call to printf
. Anders Kaseorg was kind enough to point out--that g++
recognizes the specific sequence printf("%s
", foo);
is equivalent to puts(foo);
, and generates code accordingly (i.e., generates code to call puts
instead of printf
). Moving the format string to a global array, and passing that as the format string produces identical output, but forces it to be produced via printf
instead of puts
. Of course, it's possible they might optimize around this some day as well, but at least for now (g++ 5.1) a test with g++ -O3 -S
confirms that it's actually calling printf
(where the previous code compiled to a call to puts
).
这篇关于混合 cout 和 printf 以获得更快的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!