获取程序运行时间以判别算法优劣

clock():捕捉从程序开始运行到clock()被调用所耗费的时间,这个时间单位是clock tick,即“时钟打点”。

常数CLK_TCK:机器时钟每秒所走的时间打点数

源代码示例:

#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;
}

例如:计算下面式子的两个算法比较。



源代码:

#include <stdio.h>
#include <math.h>
#include <time.h>
clock_t start,stop;
double duration;
#define MAXN 10		//多项式项数,即多项式最大阶数加一 
double fun1(double a[],int n,double x);//n为数组最大下标 
double fun2(double a[],int n,double x);
int main()
{
	int i;
	double a[MAXN];	//存储系数
	for(i=0;i<MAXN;i++){//初始化 
		a[i]=i;
	} 
	start=clock();
	fun1(a,MAXN,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();
	fun2(a,MAXN,1.1);
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK;
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
    return 0;
}
double fun1(double a[],int n,double x){//直接逐项计算 
	int i;
	double result=a[0];
	for(i=1;i<=n;i++){
		result+=(a[i]*pow(x,i));
	}
	return result;
}
double fun2(double a[],int n,double x){//将f(x)看成f(x)=a0+x*(a1+x*(...(an-1+x*(an))...)) 
	int i;
	double result=a[n];
	for(i=n;i>0;i--){
		result=a[i-1]+x*result;
	}
	return result;
}

运行结果:


之所以结果都是0,这是因为程序跑得太快,捕捉时间太短。于是,可以利用重复多次运行程序方法进行比较。

修改代码如下:

#include <stdio.h>
#include <math.h>
#include <time.h>
clock_t start,stop;
double duration;
#define MAXK 1e7	//被测函数最大重复调用次数 
#define MAXN 10		//多项式项数,即多项式最大阶数加一 
double fun1(double a[],int n,double x);//n为数组最大下标 
double fun2(double a[],int n,double x);
int main()
{
	int i;
	double a[MAXN];	//存储系数
	for(i=0;i<MAXN;i++){//初始化 
		a[i]=i;
	} 
	start=clock();
	for(i=0;i<MAXK;i++){//重复调用函数以获得充分多的时钟打点数 
		fun1(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;//计算函数单次运行时间 
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration1=%6.2e\n",duration);
	
	start=clock();
	for(i=0;i<MAXK;i++){
		fun2(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
    return 0;
}
double fun1(double a[],int n,double x){//直接逐项计算 
	int i;
	double result=a[0];
	for(i=1;i<=n;i++){
		result+=(a[i]*pow(x,i));
	}
	return result;
}
double fun2(double a[],int n,double x){//将f(x)看成f(x)=a0+x*(a1+x*(...(an-1+x*(an))...)) 
	int i;
	double result=a[n];
	for(i=n;i>0;i--){
		result=a[i-1]+x*result;
	}
	return result;
}

运行:


可见算法1的要比算法2大得多,算法2更好。


再如:

源代码:

#include <stdio.h>
#include <math.h>
#include <time.h>
clock_t start,stop;
double duration;
#define MAXK 1e5	//被测函数最大重复调用次数 
#define MAXN 101	//多项式项数,即多项式最大阶数加一 
double fun1(double x);
double fun2(double x);
int main()
{
	int i;
	start=clock();
	for(i=0;i<MAXK;i++){//重复调用函数以获得充分多的时钟打点数 
		fun1(1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;//计算函数单次运行时间 
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration1=%6.2e\n",duration);
	
	start=clock();
	for(i=0;i<MAXK;i++){
		fun2(1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
    return 0;
}
double fun1(double x){//利用递归逐项累加 
	int i;
	double result=1.0;
	for(i=1;i<MAXN;i++){
		result+=(pow(x,i)/i);
	}
	return result;
}
double fun2(double x){//先对加数项进行预算 
	int i=1;
	double temp=x;
	double result=1.0;
	while(i<MAXN){
		result+=x;
		x*=temp*i/(i+1);
		i++;
	}
	return result;
}


注意,这里的最大重复调用次数是1e5

运行效果:


算法还是不够简洁,可以仿照上面的例子,利用数组初始化。

修改代码如下:

#include <stdio.h>
#include <math.h>
#include <time.h>
clock_t start,stop;
double duration;
#define MAXK 1e5	//被测函数最大重复调用次数 
#define MAXN 101	//多项式项数,即多项式最大阶数加一 
double fun1(double a[],int n,double x);
double fun2(double a[],int n,double x);
int main()
{
	int i;
	double a[MAXN];
	for(i=1;i<MAXN;i++){
		a[i]=1.0/i;
	}
	start=clock();
	for(i=0;i<MAXK;i++){//重复调用函数以获得充分多的时钟打点数 
		fun1(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;//计算函数单次运行时间 
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration1=%6.2e\n",duration);
	
	start=clock();
	for(i=0;i<MAXK;i++){
		fun2(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
    return 0;
}
double fun1(double a[],int n,double x){//利用递归逐项累加 
	int i;
	double result=1.0;
	for(i=1;i<MAXN;i++){
		result+=(pow(x,i)*a[i]);
	}
	return result;
}
double fun2(double a[],int n,double x){//先对加数项进行预算 
	int i=1;
	double temp=x;
	double result=1.0;
	while(i<MAXN){
		result+=x;
		x*=temp*a[i+1]/a[i];
		i++;
	}
	return result;
}

效果:


额,仿佛也还是那回事敲打。那再思考下,既然在第一个例子中“将f(x)看成f(x)=a0+x*(a1+x*(...(an-1+x*(an))...))”那么这道题也可以用同样的思想:

#include <stdio.h>
#include <math.h>
#include <time.h>
clock_t start,stop;
double duration;
#define MAXK 1e5	//被测函数最大重复调用次数 
#define MAXN 101	//多项式项数,即多项式最大阶数加一 
double fun1(double a[],int n,double x);
double fun2(double a[],int n,double x);
double fun3(double a[],int n,double x);
int main()
{
	int i;
	double a[MAXN];
	for(i=1;i<MAXN;i++){
		a[i]=1.0/i;
	}
	start=clock();
	for(i=0;i<MAXK;i++){//重复调用函数以获得充分多的时钟打点数 
		fun1(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;//计算函数单次运行时间 
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration1=%6.2e\n",duration);
	
	start=clock();
	for(i=0;i<MAXK;i++){
		fun2(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;
	printf("ticks1=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
	
	start=clock();
	for(i=0;i<MAXK;i++){
		fun3(a,MAXN,1.1);
	}
	stop=clock();
	duration=((double)(stop-start))/CLK_TCK/MAXK;
	printf("ticks3=%f\n",(double)(stop-start));
	printf("duration3=%6.2e\n",duration);
    return 0;
}
double fun1(double a[],int n,double x){//利用递归逐项累加 
	int i;
	double result=1.0;
	for(i=1;i<MAXN;i++){
		result+=(pow(x,i)*a[i]);
	}
	return result;
}
double fun2(double a[],int n,double x){//先对加数项进行预算 
	int i=1;
	double temp=x;
	double result=1.0;
	while(i<MAXN){
		result+=x;
		x*=temp*a[i+1]/a[i];
		i++;
	}
	return result;
}
double fun3(double a[],int n,double x){
	int i;
	double result=a[MAXN-1];
	for(i=MAXN-1;i>1;i--){
		result=a[i-1]+x*result;
	}
	return result+1.0;
} 


跑了几次,感觉2和3差不多... 敲打



那就酱吧。敲打

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值