C言語:clock関数を使ってある処理にかかった時間を計測する

C言語初級カテゴリのロゴ画像 C言語初級

C言語のclock()関数を使うとある処理に掛かる時間計測が可能です。
この記事では、サンプルプログラムを使ってclock関数の利用例を示します。

clock関数とは?

clock()関数は、ヘッダファイルtime.hに定義された関数です。

clock関数

引数 なし
戻り値 long型
プログラムを実行してからのCPU時間
使用例 long t;
t = clock();

CPU時間というのは、プログラムの起動時から現時点までのカウンタです。
例えば1秒間に1000クロックという設定であれば、2500というCPU時間は、

2500 ÷ 1000 = 2.5秒

を表すことになります。

基本的な利用例

clock関数を実行した時点でのCPU時間が返されるため、プログラムの冒頭でclock()を実行しても0が返されてしまいCPU時間が確認出来ません。
そこで何か負荷のかかる処理をしてからclock()関数を実行してみます。(今回はprintfで適当な文字列を10000回表示しています)

clock_cpu_time.c

#include <stdio.h>
#include <time.h>

int main(void)
{
	int i;
	long cpu_time;

	/* 負荷を掛ける処理(適当です) */
	for(i=0; i<10000; i++){
		printf("計測中...\n");
	}

	/* CPU時間をチェック */
	cpu_time = clock();

	printf("CPU時間: %d\n", cpu_time);

	return 0;
}

実行結果
C言語:clock関数を使ってある処理にかかった時間を計測する

私のコンパイラ環境では1000クロックで1秒のため、上記の実行結果であれば、実際は12.922秒掛かったことになります。

同じブログラムを2回目に実行した結果です。

C言語:clock関数を使ってある処理にかかった時間を計測する

不思議ですよね。1秒も掛かっていません。
これは1度実行したプログラムがCPUのキャッシュメモリに保存されているために起きる現象だと考えられます。

CLOCKS_PER_SEC定数を使ってCPU時間を秒に直す

clock関数で利用するために定数としてCLOCKS_PER_SECが宣言されています。
1秒間にCPUのクロック数がいくつカウントされるかを定義したものです。
gccコンパイラやBorlandのC++コンパイラ(bcc32)では1000と定義されていました。(正確にはgccでは1000、bcc32では1000.0)

今回私が利用したWindows環境のコンパイラではCLOCKS_PER_SEC定数は1000でしたが、お使いの環境によっては100000で定義されている可能性もあるわけで、CPU時間を秒に直す場合には、このCLOCKS_PER_SEC定数を利用するのが安全です。

CLOCKS_PER_SECを使って取得したCPU時間(clock関数の値)を秒になおすには、

clock() / CLOCKS_PER_SEC

とします。
この場合代入する変数としてはdouble型にしておく必要があります。

実際のサンプルを示します

clock_cpu_time2.c

#include <stdio.h>
#include <time.h>

int main(void)
{
	int i;
	long cpu_time;
	double sec;

	/* 負荷を掛ける処理(適当です) */
	for(i=0; i<10000; i++){
		printf("計測中...\n");
	}

	/* CPU時間をチェック */
	cpu_time = clock();

	/* 秒に直す */
	sec = (double)cpu_time / CLOCKS_PER_SEC;

	printf("%f秒\n", sec);

	return 0;
}

実行イメージ
C言語:clock関数を使ってある処理にかかった時間を計測する

あくまでCPU時間のため、精度がミリ秒まであるとまでは言えませんが、手元のストップウォッチと計測を比べるとほぼ一致していました。

以上、clock関数を使ってある処理にかかった時間を計測するでした。

関連項目

コメント

  1. 匿名 より:

    実はキャッシュはメモリにはないんですよね

    • dennou より:

      ほんとだ!そうでした。
      キャッシュはCPUにあるんでした。
      該当箇所を修正しておきました。ありがとうございます。

タイトルとURLをコピーしました