隨筆 - 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快一些


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM