Site icon MkS

[C/C++] 計算程式效率 & 執行時間

X2EAZ4EAK3

在一些程式競賽或一些線上程式解題系統中,複雜的程式敘述常常有一些程式執行時間不得超過幾秒的規定,當然自己 Debug 的時候,應該都會有個底,但為了更加確認 C++ 計算程式效率,可以透過時間函數來取得程式正確的執行時間作為依據,來當作一個比較的基準。


前言

先透過簡單的小題目來測試執行時間,不過像這種小程式用膝蓋想一定不可能超過兩秒,但如果你在競賽過程中,程式的效率自己無法拿捏的時候,或許測試效率所得到的依據會是你很重要的參考指標。

備註:有部分程式編譯工具有提供程式結束後自動 pause 以及印出程式執行時間,例:Code::blockOrwell DevC++

題目

請輸入正整數 n <= 20,輸出一個 n 層的倒三角形。例如,n = 5 時輸出如下:

5 
######### 
 ####### 
  ##### 
   ### 
    #

需要的表頭及函數

既然是談時間,當然少不了 <time.h> 了,函數的部分則是建置在其中的 clock() ,函數 clock() 會在程式一執行的時候按下碼表,也就是說程式一執行便會開始計時。

如何使用

現在知道 clock() 函數的功能是程式一執行到結束的時間,所以我們只需要在程式末端 return 之前加入。

cout << (double)clock() / CLOCKS_PER_SEC << "S";c

應該會有網友們好奇,為什麼要除上 CLOCKS_PER_SEC,事實上 CLOCKS_PER_SEC 是常數,其數值固定為 1000由於 clock() 是以毫秒來計算程式所執行的時間,所以透過除上 CLOCKS_PER_SEC 來呈現我們熟悉的秒數。

是否有人開始質疑站長不太會寫程式,怎麼這麼簡單的程式執行效率這麼差,其實並不是這樣的,由於程式一執行就開始計時,同時包含視窗跳出以及手動輸入測資的時間都包含在內,所以站長刻意拖了約 15 秒鐘之後再輸入測資,而得到 15.419 S 的結果,至於略過輸入時間來檢視程式效率的方法,請往下看下去。

備註:下方是由 Code::Block 自動加入:

Process returnd 0 <0x0> execution time : 秒數 s
Press any key to continue.

解決辦法

透過浮點數或雙精度來宣告 START、END。

double START,END; START = clock();
/*---要計算的程式效率區域---*/
END = clock();
cout << (END - START) / CLOCKS_PER_SEC << endl;
double START,END; START = clock();
* 感謝網友 jerrylin 提出程式碼的錯誤修正 :)

透過上方的程式碼就可以檢測出某部分的程式效率,當然也可以用來檢測遞迴函數的執行效率,其原理是先將目前的時間存入浮點變數 START,再將程式結束的時間存入浮點變數 END 中,最後只需要將程式 END 減去 START,就可以獲得此段程式碼作業時間。

由於有除去常數 CLOCKS_PER_SEC,所以得結果如下。

程式所執行所花費:35.217 //單位為秒 相當於 35217毫秒
進行運算所花費的時間:0.005 //單位為秒 相當於 5毫秒

補充:若未除去常數 CLOCKS_PER_SEC,則直接得毫秒。

程式所執行所花費:35217 // 單位 ms 
進行運算所花費的時間:5 // 單位 ms

備註:如果參加競賽使用此方法檢測,請記得在提交程式碼之前將印出的部分拿掉或註解掉。

Code

本題測試的題目解答,有興趣或有疑問的朋友們可以自行複製並測試。

#include <iostream> 
#include <time.h> 
using namespace std; 
int main (){ 
	int n = 5;
	cin >> n;
	if ( n > 20) {
		cout << "Error";
		return 1;
	} 
	double START,END;
	START = clock();
	for (int i = 0 ; n >= 1 ; n--, i++){
		for (int j = 1 ; j <= 1 + 2*(n-1) ; j++){
			cout << "#"; 
		}
		cout << endl;
		for (int j = 0 ; j <= i ; j++){
			cout << " ";
		}
	}
	END = clock();
	cout << endl << "程式執行所花費:" << (double)clock()/CLOCKS_PER_SEC << " S";
	cout << endl << "進行運算所花費的時間:" << (END - START) / CLOCKS_PER_SEC << " S" << endl;
	return 0; 
}

更新:

2019/2/19 更新: 由於部分程式碼因為樣式更新,產生跑版,以及 Url 編碼亂入問題,已經想辦法修正,但程式碼並沒有再次驗證是否有完全修復,如果出現錯誤,麻煩各位給予反饋,或是自行修復,謝謝。

Exit mobile version