随笔 - 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/printfcin/cout本身就充满玄学容易出错)。

所以,基本可以认为,在不输出浮点数的使用环境中,cout是更好的选择。

此外,在输出换行的实验中,我们发现使用cout输出'\n'比输出endl换行来快得多。这在实际使用中也可以作为常数优化。

当然,由bonus可看出,在大量输出string(如输出Yes/No类的)用cout就图一乐,真要最快还是得用puts。

upd:

事实上好像差距不大,但是cout还是比printf快一些

posted @ 2020-09-24 17:50  zimindaada  阅读(1124)  评论(12编辑  收藏  举报