C语言计算程序运行的时间
1.概念
- 函数 clock():捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间的单位是clock tick,即“时钟打点”。(C语言提供的函数,使用时要引入头文件time.h 即#include<time.h>)
- 常数 CLK_TCK:机器时钟每秒所走的始终打点数。具体数值多少因机器而异。
2.常用模板
#include<stdio.h>
#include<time.h>`
clock_t start, stop;
//clock_t是clock()函数返回值的数据变量类型
double duration;
//记录被测函数的运行时间,以秒为单位
int main()
{
//不在测试范围内的准备工作写在clock()调用之前
start = clock(); //开始计时
MyFunction(); //把被测函数添加在这里
stop = clock(); //结束计时
duration = ((double)(stop - start)) / CLK_TCK;
//其他不在测试范围内的处理写在后面,例如输出duration的值
return 0;
}
3.以两种算法计算多项式值为例
利用clock()函数比较算法效率
此前,我们先来看一下下面两个公式。
f
(
x
)
=
a
0
+
a
1
x
+
…
+
a
n
−
1
x
n
−
1
+
a
n
x
n
f
(
x
)
=
a
0
+
x
(
a
1
+
x
(
…
(
a
n
−
1
+
x
(
a
n
)
)
…
)
)
\begin{array}{l} f(x)=a_{0}+a_{1} x+\ldots+a_{n-1} x^{n-1}+a_{n} x^{n} \\ f(x)=a_{0}+x\left(a_{1}+x\left(\ldots\left(a_{n-1}+x\left(a_{n}\right)\right) \ldots\right)\right) \end{array}
f(x)=a0+a1x+…+an−1xn−1+anxnf(x)=a0+x(a1+x(…(an−1+x(an))…))
其对应的算法代码表示分别为:
//公式上
double f1(int n, double a[], double x)
{
int i;
double p = a[0];
for (i = 1; i <= n; i++)
p = p + (a[i] * pow(x,i));
return p;
}
//公式下
double f2(int n, double a[], double x)
{
int i;
double p = a[n];
for (i = n; i > 0; i--)
p = a[i-1] + x*p;
return p;
}
理解这两种算法后,再尝试下面的练习。
代码实现:
#include<stdio.h>
#include<time.h>
#include<math.h>
clock_t start, stop;
double duration;
#define MAXN 10 //多项式最大项数(0~9)
double f1(int n, double a[], double x);
double f2(int n, double a[], double x);
int main()
{
int i;
double a[MAXN]; //存储多项式的系数
for (i = 0; i < MAXN; i++)
a[i] = (double)i;
//测试f1
start = clock();
f1(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK;
printf("ticks for f1 = %lf", (double)(stop - start));
printf("duration for f1 = %6.2e\n", duration);
//测试f2
start = clock();
f2(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK;
printf("ticks for f2 = %lf", (double)(stop - start));
printf("duration for f2 = %6.2e\n", duration);
return 0;
}
运行结果如图:
这是由于程序运行的太快,它的时间都可能达不到一个tick。这种情况我们需要换一种办法:让被测函数 重复运行 多次,使得测出的总的时钟打点间隔充分长,最后计算北侧函数平均每次运行的时间即可。
代码实现:
...
#define MAXK 1e7 //被测函数最大重复调用次数
...
int main()
{
...
start = clock();
for (i = 0; i < MAXK; i++) //函数运行MAXK次
f1(MAXN-1, a, 1.1);
stop = clock();
//计算函数单次运行的时间
duration = ((double)(stop - start)) / CLK_TCK / MAXK;
...
return 0;
}
不难看出,在不同的机器上运行结果不同,但是数量级以及f1,f2的数量级差都是相同的。基于此,很容易比较出f2算法优于f1算法。