問題描述
在執行一些測試后,我注意到 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 以獲得更快的輸出的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!