随笔 - cout与printf写速度比较
upd in 20210927 : 部分测试在NOI Linux 2.0虚拟机下测试。测试环境如下:
CPU : i3 1115G4 @ 1C2T
RAM :2G
编译选项 g++ test.cpp -o test -std=c++14
0.前置环境:
计算机配置:
CPU : i5 7500
RAM : 8G
系统:Win7 64位
测试硬盘:intel 256G SSD
无吸氧优化,使用C++98, GCC 4.9.2 64 Bit
1. cout、printf输出字符串,无换行
代码:
//test 1 : cout VS printf in output string
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;
int T = 10000000;//1e7
clock_t st, co, pri;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(int i = 1; i <= T; ++i){
cout << "LKYAKIOI";
}
co = clock();
for(int i = 1; i <= T; ++i){
printf("LKYAKIOI");
}
pri = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-co) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 0.617s
printf : 21.279s
2. cout、printf输出int内整数,无换行
代码:
//test 2 : cout VS printf in output int
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;
const int T = 10000000;//1e7
clock_t st, co, pri, pus, puc;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(int i = 1; i <= T; ++i){
cout << i;
}
co = clock();
for(int i = 1; i <= T; ++i){
printf("%d", i);
}
pri = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-co) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 0.723s
printf : 21.012s
upd : 于NOI Linux环境下的结果:
cout : 0.415719s
printf : 0.458123s
cout : 0.391156s
printf : 0.467886s
cout : 0.421311s
printf : 0.547006s
3. cout、printf输出long long内整数,无换行
代码:
//test 3 : cout VS printf in output long long
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;
const int T = 10000000;//1e7
clock_t st, co, pri, pus, puc;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(int i = 1; i <= T; ++i){
cout << 1ll * i * T;
}
co = clock();
for(int i = 1; i <= T; ++i){
printf("%lld", 1ll*i*T);
}
pri = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-co) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 1.024s
printf : 23.381s
4. cout、printf输出double,保留6位小数,无换行
为了模拟常见环境,我们保留6位小数,所以用了setprecision()
函数
代码:
//test 4 : cout VS printf in output double
#include <iostream>
#include <cstdio>
#include <ctime>
#include <iomanip>
using namespace std;
const int T = 10000000;//1e7
clock_t st, co, pri, pus, puc;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(double i = 1; i <= T; ++i){
cout << fixed << setprecision(6) << 11.45141919 * i;
}
co = clock();
for(double i = 1; i <= T; ++i){
printf("%.6lf", 11.45141919 * i);
}
pri = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-co) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 30.008000s
printf : 29.687000s
5. cout、printf输出换行(对cout同时测试endl和\n)
代码:
//test 5 : cout VS printf in endline
#include <iostream>
#include <cstdio>
#include <ctime>
#include <iomanip>
using namespace std;
const int T = 10000000;//1e7
clock_t st, co, el, pri, pus, puc;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(int i = 1; i <= T; ++i){
cout << '\n';
}
co = clock();
for(int i = 1; i <= T; ++i){
cout << endl;
}
el = clock();
for(int i = 1; i <= T; ++i){
printf("\n");
}
pri = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "endl : " << 1.0*(el-co) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-el) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 0.401s
endl : 11.698s
printf : 18.655s
Bonus: cout、printf、puts、putchar输出字符串,无换行
代码:
//bonus : cout VS printf VS puts VS putchar at output string
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;
int T = 10000000;//1e7
clock_t st, co, pri, pus, puc;
signed main(){
freopen("waste.out","w",stdout);
st = clock();
for(int i = 1; i <= T; ++i){
cout << "LKYAKIOI" << '\n';
}
co = clock();
for(int i = 1; i <= T; ++i){
printf("LKYAKIOI\n");
}
pri = clock();
for(int i = 1; i <= T; ++i){
puts("LKYAKIOI");
}
pus = clock();
for(int i = 1; i <= T; ++i){
putchar('L');putchar('K');putchar('Y');
}
puc = clock();
freopen("result.out","w",stdout);
cout << "cout : " << 1.0*(co-st) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "printf : " << 1.0*(pri-co) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "puts : " << 1.0*(pus-pri) / (CLOCKS_PER_SEC) << "s" << endl;
cout << "putchar: " << 1.0*(puc-pus) / (CLOCKS_PER_SEC) << "s" << endl;
return 0;
}
结果:
cout : 1.034s
printf : 22.068s
puts : 0.978s
putchar: 0.968s
结论
除了在输出double的时候速度比printf
略慢(并且很有可能是因为使用了setprecision()
函数),在其他的时候基本上就是碾压。并且本文中并没有给cout
关闭流同步——这在实际使用中很常见(毕竟不太可能会在同一篇代码中使用两个年代的东西,而且本身同时用scanf/printf
与cin/cout
本身就充满玄学容易出错)。
所以,基本可以认为,在不输出浮点数的使用环境中,cout
是更好的选择。
此外,在输出换行的实验中,我们发现使用cout
输出'\n'
比输出endl
换行来快得多。这在实际使用中也可以作为常数优化。
当然,由bonus可看出,在大量输出string
(如输出Yes/No
类的)用cout就图一乐,真要最快还是得用puts。
upd:
事实上好像差距不大,但是cout
还是比printf
快一些