一、cout
- 优点:
- C++标准库中的对象,类型安全,自动处理不同数据类型输出
- 支持链式调用,代码可读性高。(链式调用是编程中一种技术,允许在一个表达式中连续调用同一对象的方法或运算符。
cout就
重载了<<
运算符,使其每次调用后都返回cout自身引用,令其可在同一表达式中连续调用多次) - 支持国际化(选择正确字符编码,且输出设备或终端支持该编码,保证字符正确显示,从而满足多语言和多文化需求,通常影响到日期和时间格式、货币和数值格式等)和多字节字符(如:UTF-8编码中,英文字符只需1个字节,而汉字或表情符需要多个字节)
- 可与C++的字符串流和格式化库(如
<iomanip>
)一起使用
- 缺点:
- 比C语言的I/O慢,因为它涉及更多的类型检查和封装
- 对于大量数据输出,可能不如一些低级输出方式高效
二、printf
- 优点:
- C语言标准函数,格式化能力强大,灵活
- 通常比
cout
快,因为它是宏定义,直接操作底层缓冲区
- 缺点:
- 需要手动格式化,易出错(如缓冲区溢出)
- 不是类型安全的,需要确保传递给
printf
的参数类型与格式说明符匹配
三、sprintf
- 优点:
- 类似于
printf
,但输出到字符串而不是标准输出 - 可以用来构造复杂格式的字符串
- 类似于
- 缺点:
- 容易遭受缓冲区溢出攻击,如果输出数据超过目标字符串的容量
- 不是类型安全的,需要手动格式化
- 比
printf
慢,因为它需要分配和复制内存
四、putchar
- 优点:
- 简单,用于输出单个字符
- 直接,快速,只处理一个字符
- 缺点:
- 功能有限,只能输出字符,不适合格式化输出
- 需要手动管理输出的格式和换行
五、putchar + register
- 优点:
register
关键字(在大多数现代编译器中已不建议使用,可能被忽略)提示编译器该变量应该存储在寄存器中,可能提高访问速度
- 缺点:
- 与普通
putchar
相比,性能提升可能微乎其微,因为现代编译器优化已经很好 - 使用
register
关键字可能会限制变量的作用域和可见性
- 与普通
测试代码:
#include <iostream>
#include <chrono>
#include <vector>
#include <cstdio>
using namespace std;
using namespace std::chrono;
inline void W(register char c) {
putchar(c);
}
int main() {
//int num = 0;
//int total = 0;
//for (int i = 0; i < 10; i++) {
// cin >> num;
// total += num;
//}
//cout << total / 10;
vector<string> t;
t.push_back("123");
t.push_back("456");
string ss = "123";
char buffer[10];
auto s = high_resolution_clock::now();
auto e = high_resolution_clock::now();
s = high_resolution_clock::now();
for (auto& it : t) {
cout << it << '\n';
}
//cout << ss << '\n';
e = high_resolution_clock::now();
cout <<"cout: "<< duration_cast<microseconds>(e - s).count() << endl;
s = high_resolution_clock::now();
for (auto& it : t) {
printf("%s\n", it.c_str());
}
//printf("%s\n", ss.c_str());
e = high_resolution_clock::now();
cout <<"printf: "<< duration_cast<microseconds>(e - s).count() << endl;
s = high_resolution_clock::now();
for (auto& it : t) {
sprintf_s(buffer,"%s\n", it.c_str());
printf("%s", buffer);
}
//sprintf_s(buffer,"%s\n", ss);
e = high_resolution_clock::now();
cout << "sprintf_s: " << duration_cast<microseconds>(e - s).count() << endl;
s = high_resolution_clock::now();
for (auto& it : t) {
for (auto& c : it) {
putchar(c);
}
putchar('\n');
}
//for (auto& it : ss) {
// putchar(it);
//}
//putchar('\n');
e = high_resolution_clock::now();
cout <<"putchar: "<< duration_cast<microseconds>(e - s).count() << endl;
s = high_resolution_clock::now();
for (auto& it : t) {
for (auto& c : it) {
W(c);
}
putchar('\n');
}
//for (auto& c : ss) {
// W(c);
//}
//putchar('\n');
e = high_resolution_clock::now();
cout << "register + putchar: " << duration_cast<microseconds>(e - s).count() << endl;
return 0;
}
输出:
在windows11 C++20 中,我测试时,绝大部分情况下,还是sprintf_s最快,不过一般与printf也就相差几毫秒到几十毫秒,所以综合来看,可能printf更好些,使用简单快捷