算法中的精确时间计数器的应用
来源:互联网 发布:菜鸟也能数据分析 编辑:程序博客网 时间:2024/04/30 14:31
算法中的精确时间计数器的应用
流浪狗 2006.3
评价一个算法的好坏,在运行时所消耗的时间是一个很重要的参数,可以反应出该算法的时间复杂度。要测试一个程序运行时所消耗的时间,我们可以写出很多种算法。很多编译器都提供了相关的时间函数库,还有系统的API等等。但是,我们会发现这些函数在程序中根本本能得到满意的结果。有时候设计得很好的算法,或者很小的算法,在运行的时候非常快,在1ms以内,这时候要测试这个算法所消耗的时间就是一件不容易的事情。
在头文件time.h中有个函数clock(),返回clock_t的类型,可以通过两次调用clock函数,来确定时间间隔。API中有一个函数叫做GetTickCount的函数,可以得到当前计算机运行的时间,它返回一个DWORD值。在程序短之前加入一句DWORD t=GetTickCount();在程序段后加入t=GetTickCount()-t,则t的结果就是此程序段运行的时间。但是我们会发现很多程序段的结果输出都是0ms,所以我们需要比这个精度更高的函数。有没有这样的函数呢,通过查询MSDN,发现有两个函数满足要求,QueryPerformanceFrequency和QueryPerformanceCounter,它可以精确到0.5微秒,具体说明可以参见MSDN。为了方便我们以后在对算法时间的计算,我们把他封装成一个计时器类:
#include <windows.h>
#include<iostream.h>
using namespace std;
class TimeTake{
public:
TimeTake():dCount(0)
{
// 获得计数器的时钟频率
QueryPerformanceFrequency(&lPoint);
dFreq=(double)lPoint.QuadPart;
}
~TimeTake()
{
}
void print()
{
cout<<dCount<<" ms elapse in the algothim!"<<endl;
}
void start()
{
//第一次取计数器的值
QueryPerformanceCounter(&lPoint);
lPart=lPoint.QuadPart;
}
void end()
{
//再一次取计数器的值并计算中间的时间间隔,表示成ms
QueryPerformanceCounter(&lPoint);
dCount=(double(lPoint.QuadPart-lPart)/dFreq)*1000;
}
private:
LARGE_INTEGER lPoint;
LONGLONG lPart;
double dFreq, dCount;
};
我们可以写三个算法,用其对他们进行测试,下面几个算法都是求最大公约数的问题,第二个是第一个算法的改进,第三个是求使得a*m+b*n=d的最大公因数,详细算法如下:
DWORD mode1(DWORD m,DWORD n)
{
int r=m%n;
while(r!=0)
{
m=n;
n=r;
r=m%n;
}
return n;
}
DWORD mode2(DWORD m,DWORD n)
{
DWORD r,result;
while(1)
{
r=m%n;
if(r==0)
{
result=n;
break;
}
m=n%r;
if(m==0)
{
result=r;
break;
}
n=r%m;
if(n==0)
{
result=m;
break;
}
}
return result;
}
//求接a,b使得am+bn=d,d为最大公倍数
DWORD mode(DWORD m,DWORD n,int& a,int& b)
{
int al,bl; //求解al,bl使得al*m+bl*n=c;
DWORD c,d,q,r,t;
c=m;
d=n;
a=bl=0;
b=al=1;
while(1)
{
q=c/d;
r=c%d;
if(r==0)
break;
else
{
c=d; d=r;
t=al;
al=a;
a=t-q*a;
t=bl;
bl=b;
b=t-q*b;
}
}
return d;
}
然后编写主程序进行测试:
int _tmain(int argc, _TCHAR* argv[])
{
TimeTake tk;
int a,b;
DWORD m,n,d1,d2;
cout<<"please input m and n"<<endl;
cin>>m>>n;
while(n==0)
{
cout<<"n can't be zero,please input n again!"<<endl;
cin>>n;
}
tk.start();
d1=mode1(m,n);
cout<<"the mode 1's result is "<<d1<<endl;
tk.end();
tk.print();
tk.start();
d2=mode2(m,n);
cout<<"the mode 2's result is "<<d2<<endl;
tk.end();
tk.print();
tk.start();
d2=mode(m,n,a,b);
cout<<"the result is "<<a;
if(b>=0)
cout<<"*m+"<<b<<"*n="<<d2<<endl;
else
cout<<"*m"<<b<<"*n="<<d2<<endl;
tk.end();
tk.print();
return 0;
}
输出结果如下:
please input m and n
150
456
the mode 1's result is 6
1.9469 ms elapse in the algothim!
the mode 2's result is 6
1.23787 ms elapse in the algothim!
the result is -3*m+1*n=6
1.18842 ms elapse in the algothim!
Press any key to continue
通过多组数据的输入,我们可以肯定的是第二种算法比第一种算法用的时间少,因为第二种算法避免了第一种算法的重复赋值。但是第三种算法与前两种算法相比,体现出时间的不确定性,有时候时间处于前两种算法之间,有时候又比前两种都少。从表面上来看,第三种算法比前两种做的事情都要多,但是为什么他用的时间最少呢?
- 算法中的精确时间计数器的应用
- 一个易用,高效,精确的纳秒级C#时间计数器
- 延时程序耗费时间的精确算法
- js中的时间计数器及对于时间的操作
- 如何精确计算出一个算法的CPU运行时间?
- 如何精确计算出一个算法的CPU运行时间
- 11如何精确计算出一个算法的CPU运行时间?
- 计数器定时器的应用
- ZOJ1095计数器的应用
- redis的计数器应用
- JSP页面中的精确到秒的时间控件
- JSP页面中的精确到秒的时间控件
- 【时间计数器】安卓应用详细信息
- 51定时器/计数器的深入研究-精确定时
- 精确时间内的叙述:时间
- 精确的时间计时--QueryPerformanceCounter
- PC的时间精确吗?
- C#精确计算算法运行时间
- SourceForge访问方法,解被封痛苦之中国伟大的程序员们!
- J2ME中文教程 2 CLDC简介
- J2ME中文教程 3 MIDP高级UI 的使用
- J2ME中文教程 4 MIDP低级UI的使用
- J2ME中文教程 5 MIDP的持久化解决方案
- 算法中的精确时间计数器的应用
- 看马大帅3
- J2ME中文教程 6 GAME API
- fileStream
- >中感动我的台词
- 把库存的商品热销出去----zt
- QQ签名分析与感想(哥们版)
- 获得光标在文本区中的行列位置
- DENX U-Boot及Linux使用手册