[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";

應該會有網友們好奇,為什麼要除上 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;

* 感謝網友 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 編碼亂入問題,已經想辦法修正,但程式碼並沒有再次驗證是否有完全修復,如果出現錯誤,麻煩各位給予反饋,或是自行修復,謝謝。


4 則迴響

  • KaiWen Weng

    2015-05-04

    時間單位用錯了,印符號不致於慢到一秒,用毫秒。

    回復
    • SiaoT

      2015-05-04

      內文部分有提到是以毫秒為單位,
      但圖片部分可能會造成誤解,
      已經將圖片更新,
      並解對時間單位多做強調了,
      感謝您的提醒^^。

      回復
  • jerrylin

    2018-05-18

    /*—要計算的程式效率區域—*/
    END = clock();
    cout << (END – START) – CLOCKS_PER_SEC << endl;

    上據是否為(END – START) /CLOCKS_PER_SEC

    回復
    • MksYi

      2018-05-27

      jerrylin 你好:
      你說的沒有錯
      在本文章範例一的部分應為 (END – START) / CLOCKS_PER_SEC
      已經修正了 感謝你的回饋 🙂

      回復

發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料