直接的回答是,是的,没关系。
很多人都提出了关于如何提高速度的各种想法,但对于哪种方法最有效似乎存在相当多的分歧。我决定编写一个快速测试程序,以至少了解哪些技术做了什么。
#include <iostream>
#include <string>
#include <sstream>
#include <time.h>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <stdio.h>
char fmt[] = "%s\n";
static const int count = 3000000;
static char const *const string = "This is a string.";
static std::string s = std::string(string) + "\n";
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 << "\n";
}
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 << "\n";
}
void use_cout_unsync() {
std::cout.sync_with_stdio(false);
for (int i=0; i<count; i++)
std::cout << string << "\n";
std::cout.sync_with_stdio(true);
}
void use_stringstream() {
std::stringstream temp;
for (int i=0; i<count; i++)
temp << string << "\n";
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, "\n"), 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 上运行了它。一次运行的输出(输出重定向到磁盘文件)如下所示:
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
正如预期的那样,结果各不相同,但有几点我觉得很有趣:
- 写入 NUL 设备时 printf/puts 比 cout 快得多
- 相当多的建议优化效果不大
- 到目前为止,最大的优化是避免 endl
- cout.write 给出了最快的时间(虽然可能不是很大
我最近编辑了代码以强制调用printf
. Anders Kaseorg 非常友好地指出——g++
识别特定序列printf("%s\n", foo);
等同于puts(foo);
,并相应地生成代码(即,生成要调用的代码puts
而不是printf
)。将格式字符串移动到全局数组,并将其作为格式字符串传递会产生相同的输出,但会强制它通过printf
而不是puts
. 当然,他们也有可能在某一天围绕这一点进行优化,但至少现在(g++ 5.1)一个测试g++ -O3 -S
确认它实际上正在调用printf
(之前的代码编译为对 的调用puts
)。