【分享+开源+教程】用FreePascal计算算法时长(精确到微秒级别!)
pascal吧
全部回复
仅看楼主
level 5
CHU_overlord 楼主
对于一个算法而言,运行时所花费的时间越短,算法的质量自然越佳。
(算法时长对于大型3D游戏非常重要,当然了,有时候也不必过分计较)
但是如何计算我的算法时长呢?掐秒表?显然不可能。
方法肯定是有的,就是调用Windows的API。
FreePascal提供了Windows单元,其中封装了绝大部分的常用API。
其中就有我们需要用到的这几个命令。
命令名称=================来自单元========说明========用法
QueryPerformanceFrequency==Windows========取得CPU的频率(你可以在我的电脑-属性看到他的大致值,这里是精确值)
QueryPerformanceFrequency(某变量:Int64) //这个变量用于储存返回值
QueryPerformanceCounter====Windows========取得系统的时钟值
QueryPerformanceCounter(某变量:Int64) //这个变量用于储存返回值
Exec===================Dos============运行外部程序
Exec(程序,参数);
简单说明下方法。Windows自带一个计时器,处理器每运行一个周期,计时器就会加1。注意这个计时器一开机就会不断运行,不会停止,所以数值很大,要用Int64来储存。
那么要知道我程序运行的时长就要这样,弄两个变量a,b
QueryPerformanceCounter(a);
运行程序……………………
QueryPerformanceCounter(b);
再b-a就是运行这个程序所花费的时间了。
但是这个结果还不是时间,准确的说是处理器经过的周期。
于是时间就是 (b-a)/处理器频率
下面是源码:
program ProgramTimer;//名称随便
uses Windows,Dos;//用到了这两个单元
Var CPUFrq:Int64;//储存处理器频率
     TimeS:Int64;//记录开始的时间
     TimeE:Int64;//记录结束的时间
     ElapsedTime:Double;//计算流逝时间
begin
   QueryPerformanceFrequency(CPUFrq);//取得处理器频率
   QueryPerformanceCounter(TimeS);//取得计数器的值
   Exec('C:\1.exe','');//这里执行你的程序、过程、函数
   QueryPerformanceCounter(TimeE);//取得计数器的值
   ElapsedTime:=(TimeE-TimeS)/CPUFrq;//计算流逝时间
//注意:最后的结果精确到微秒级别,乘上1000就是毫秒,以此类推
   writeln(ElapsedTime);//输出,不多说了
end.
呼呼 终于写完了~~~
2010年03月06日 11点03分 1
level 5
CHU_overlord 楼主
这里好闲啊~~~~~~~~~~~~~~~~~~~
2010年03月06日 11点03分 2
level 1
QueryPerformanceFrequency 好像只与OS有关
Win98都是1193180
WinXP都是3579545
2010年03月06日 11点03分 3
level 5
CHU_overlord 楼主
楼上错了吧
我取出来的就不是你的值
这个值都说了是处理器频率
2010年03月06日 12点03分 4
level 5
CHU_overlord 楼主
要不然你去试试看
2010年03月06日 12点03分 5
level 1
那你用的一定不是WinXP了
我都进去API看过了,直接返回常数
2010年03月06日 12点03分 6
level 1
说明一下,WinXP我没有看过,但以前用win9x时我进去API看过了
以前我还在网上找过相关资料,在一个台湾论坛上看到有人试过不同频率CPU
但得出同样的结果,
所以我觉得它不是CPU的频率,而是windows用的计数器的频率
好奇问一下,你取到的值是多少
2010年03月06日 14点03分 7
level 5
CHU_overlord 楼主
不是吧?我再去研究下,莫非哪里看错了。
2010年03月07日 00点03分 8
level 5
CHU_overlord 楼主
我记得我取回的值是24开头的一大串,因为我cpu频率就是2.4ghz
现在不在电脑前,楼上那位请参考
http://blog.csdn.net/daoyuly/archive/2009/03/01/3947868.aspx
2010年03月07日 00点03分 9
level 5
CHU_overlord 楼主
抱歉,原文中有一处错误,现在更正一下
ElapsedTime:=(TimeE-TimeS)/CPUFrq;//计算流逝时间
//注意:最后的结果精确到秒级别,乘上1000就是毫秒,再乘1000才是微秒,其实毫秒已经足够了
写的时候没注意到,特别说明下
2010年03月07日 00点03分 10
level 1
http://blog.csdn.net/daoyuly/archive/2009/03/01/3947868.aspx
是说
机器内部计时器的时钟频率
本来我也觉得应是机器计时器频率
不过感觉更像是windows内部计时器的频率,不过应是和机器计时器频率有关的
我再去研究下[揉脸]
2010年03月07日 00点03分 11
level 5
CHU_overlord 楼主
回楼上
呵呵,你换台cpu主频不同的电脑测试下不就可以啦?
2010年03月07日 01点03分 12
level 1
换台cpu主频不同的电脑测试下,你说得好像很容易[瀑布汗~]
Win98/120MHz : 1193180
Win98/266MHz : 1193180
Win98/400MHz : 1193180
Win98/1GHz :   1193180
WinCE/1.8GHz: 1193180
Win2000/550MHz : 3579545
WinXP/700MHz :   3579545
WinXP/1GHz :    3579545
WinXP/1.8GHz :   3579545
你赶快用你的电脑测试一下吧
[瞌睡]

2010年03月07日 05点03分 13
level 5
CHU_overlord 楼主
回复13楼:
你确定你的代码正确??
。。。。。。
有够变态的,但是不管怎么说,这种计时方式是
正确的

2010年03月07日 07点03分 14
level 1
我查到取cpu的主频要用
CallNtPowerInformation
[Yeah]
2010年03月07日 07点03分 15
level 1
研究了下,发现QueryPerformanceFrequency取得是
8254 计时器 频率
ReactOS就是取8254 计时器 频率
在ReactOS中运行,显示为1193182
和Win98中的1193180差不多了
1193182*3=3579546
这就和XP的3579545差不多了[Yeah]
2010年03月07日 11点03分 16
level 5
CHU_overlord 楼主
你还是错了
我在两台不同的机器上测试所得结果完全不同
返回值就是CPU主频
2010年03月09日 13点03分 17
level 1

QueryPerformanceFrequency
QueryPerformanceCounter
计时是很普通的方法,这可不算是Copy你的方法
我翻了一下很久以前买的一本书,书上面明确写了
QueryPerformanceFrequency 是取得“高分辨率性能计数器”的频率
并不是是CPU主频
[拍砖]以前看书太不仔细了

2010年03月11日 12点03分 18
level 9
如果毫秒级别,Dos单元就够了
gettime(a,b,c,d);    //返回系统时间,a时b分c秒d毫秒
2010年03月15日 11点03分 20
level 1
GetTickCount足矣。。
2010年07月16日 08点07分 21
1 2 尾页