1.1.3 关于算法效率 - 例:计算多项式值(10:17)
例3:写程序计算给定多项式在给定点x处的值
double f( int n, double a[], double x )
{ int i;
double p = a[0];
for ( i=1; i<=n; i++ )
p += (a[i] * pow(x, i));
return p;
}
double f( 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;
}
哪一个更快?
在C语言可以使用这个函数(需要头文件#include <time.h>
)
clock():捕捉从程序开始运行到clock()被调用时所耗费的时间。这个
时间单位是clock tick,即“时钟打点”。
常数CLK_TCK(或CLOCKS_PER_SEC):机器时钟每秒所走的时钟打点数。
我们可以利用下面的函数处理:
#include <stdio.h>
#include <time.h>
clock_t start, stop;
double duration;
int main (){
start = clock();
MyFunction();
stop = clock();
duration = ((double)(stop - start))/CLK_TCK;
return 0;
}
将开始计时的时间储存在start,把被测函数加在中间,将停止计时的时间储存在stop…
选择一个具体的多项式看看:
例3:写程序计算给定多项式
在给定点 x = 1.1 处的值 f(1.1)
double f1( int n, double a[], double x )
{ int i;
double p = a[0];
for ( i=1; i<=n; i++ )
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 /* 多项式最大项数,即多项式阶数+1 */
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;
start = clock();
f1(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start))/CLK_TCK;
printf("ticks1 = %f\n", (double)(stop - start));
printf("duration1 = %6.2e\n", duration);
start = clock();
f2(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start))/CLK_TCK;
printf("ticks2 = %f\n", (double)(stop - start));
printf("duration2 = %6.2e\n", duration);
return 0;
}
看看运行结果:
如果不到一个tick,那就没有办法测了吗?
让被测函数重复运行充分多次,使得测出的总的时钟打点间隔充分长,最后计算被测函数平均每次运行的时间即可!
这里将函数修改成重复10的七次方。
#include <stdio.h>
#include <time.h>
#include <math.h>
……
#define MAXK 1e7 /* 被测函数最大重复调用次数 */
……
int main ()
{ ……
start = clock();
for ( i=0; i<MAXK; i++ ) /* 重复调用函数以获得充分多的时钟打点数*/
f1(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start))/CLK_TCK/MAXK; /* 计算函数单次运行的时间 */
printf("ticks1 = %f\n", (double)(stop - start));
printf("duration1 = %6.2e\n", duration);
……
return 0;
}
可以看到,第一个程序的效率明显低于第二个。
这道题目告诉我们,解决问题方法的效率,跟算法的巧妙程度有关。