C#中精确计时的一点收获
2010-09-01 17:32
375 查看
以下所有代码运行环境:Windows 2003, Intel(R) Core(TM) 2 Duo CPU E8400 @ 3.00GHz 2.99GHz,2.96GB内存
根据综合网上的一些文章,精确计时主要有以下几种方式
从操作系统启动到现在所经过的毫秒数,精度为1毫秒,经简单测试发现其实误差在大约在15ms左右
缺点:返回值是uint,最大值是2的32次方,因此如果服务器连续开机大约49天以后,该方法取得的返回值会归零
用法:
缺点:与GetTickCount一样,受返回值的最大位数限制。
用法:
注:经过测试,发现GetTickCount、System.Environment.TickCount也可以用timeBeginPeriod与timeEndPeriod来设置精度,最高可将精度提高到1毫秒。不知是什么原因?
用于得到高精度计时器(如果存在这样的计时器)的值。微软对这个API解释就是每秒钟某个计数器增长的数值。
如果安装的硬件不支持高精度计时器,函数将返回false需要配合另一个API函数QueryPerformanceFrequency。
QueryPerformanceFrequency返回硬件支持的高精度计数器的频率,如果安装的硬件不支持高精度计时器,函数将返回false。
用法:
该方法的原理我不是很明白,硬件知识太匮乏了。精度是ns
在C#中要用该方法必须先建立一个托管C++项目(因为要内嵌汇编),编译成DLL供c#调用,有点麻烦。
C++代码:
缺点:和QueryPerformanceCounter一样,结果不太稳定。
我的结论:常规应用下timeGetTime完全够用了,将精度调到1毫秒,大部分境况都够用。System.Diagnostics.Stopwatch由于调用方便,也推荐使用。
根据综合网上的一些文章,精确计时主要有以下几种方式
1 调用WIN API中的GetTickCount
[DllImport("kernel32")] static extern uint GetTickCount();
从操作系统启动到现在所经过的毫秒数,精度为1毫秒,经简单测试发现其实误差在大约在15ms左右
缺点:返回值是uint,最大值是2的32次方,因此如果服务器连续开机大约49天以后,该方法取得的返回值会归零
用法:
推荐[DllImport("winmm")] static extern uint timeGetTime();
常用于多媒体定时器中,与GetTickCount类似,也是返回操作系统启动到现在所经过的毫秒数,精度为1毫秒。
一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度
[DllImport("winmm")]
static extern void timeBeginPeriod(int t);
[DllImport("winmm")]
static extern void timeEndPeriod(int t);
缺点:与GetTickCount一样,受返回值的最大位数限制。
用法:
int aa = System.Environment.TickCount; Thread.Sleep(2719); Console.WriteLine(System.Environment.TickCount - aa); //单位毫秒
注:经过测试,发现GetTickCount、System.Environment.TickCount也可以用timeBeginPeriod与timeEndPeriod来设置精度,最高可将精度提高到1毫秒。不知是什么原因?
4 调用WIN API中的QueryPerformanceCounter
[DllImport("kernel32.dll ")] static extern bool QueryPerformanceCounter(ref long lpPerformanceCount);
用于得到高精度计时器(如果存在这样的计时器)的值。微软对这个API解释就是每秒钟某个计数器增长的数值。
如果安装的硬件不支持高精度计时器,函数将返回false需要配合另一个API函数QueryPerformanceFrequency。
[DllImport("kernel32")] static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);
QueryPerformanceFrequency返回硬件支持的高精度计数器的频率,如果安装的硬件不支持高精度计时器,函数将返回false。
用法:
http://delphi.xcjc.net/viewthread.php?tid=1570 未经过超频等测试,如果是真的,那该API出来的结果就可能不准。5 使用.net的System.Diagnostics.Stopwatch类 推荐
Stopwatch 在基础计时器机制中对计时器的刻度进行计数,从而测量运行时间。如果安装的硬件和操作系统支持高分辨率性能的计数器,则 Stopwatch 类将使用该计数器来测量运行时间;否则,Stopwatch 类将使用系统计数器来测量运行时间。使用 Frequency 和 IsHighResolution 两个静态字段可以确定实现 Stopwatch 计时的精度和分辨率。 实际上它里面就是将QueryPerformanceCounter、QueryPerformanceFrequency两个WIN API封装了一下,如果硬件支持高精度,就调用QueryPerformanceCounter,如果不支持就用DateTime.Ticks来计算。 用法: Stopwatch sw = new Stopwatch(); sw.Start(); Thread.Sleep(2719); sw.Stop(); Console.WriteLine(sw.ElapsedTicks / (decimal)Stopwatch.Frequency);
6 使用CPU时间戳进行更高精度计时
原文地址:http://www.chinaunix.net/jh/23/110190.html该方法的原理我不是很明白,硬件知识太匮乏了。精度是ns
在C#中要用该方法必须先建立一个托管C++项目(因为要内嵌汇编),编译成DLL供c#调用,有点麻烦。
C++代码:
long a = 0; QueryPerformanceFrequency(ref a); MLTimerDot.MLTimer timer = new MLTimerDot.MLTimer(); ulong ss= timer.GetCount(); Thread.Sleep(2719); Console.WriteLine((timer.GetCount() - ss) / (decimal)a);
缺点:和QueryPerformanceCounter一样,结果不太稳定。
我的结论:常规应用下timeGetTime完全够用了,将精度调到1毫秒,大部分境况都够用。System.Diagnostics.Stopwatch由于调用方便,也推荐使用。
相关文章推荐
- C#中精确计时的一点收获
- C#中精确计时的一点收获!!!
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#精确计时
- 关于C#中精确计时的问题
- C# WinForm编程中的一点小收获
- [导入]C# WinForm编程中的一点小收获
- C#实现精确计时,精度1ms
- 计时精度到底毫秒级别或者更高 如何使用C#制作一个精确计时器
- [导入]C# WinForm编程中的一点小收获(二)
- 今天学习C# Itext大一点收获!
- c#多态之抽象类与接口的一点收获~~
- C# Winform DataGridView 获取数据源帮顶表行状态的一点教训
- C#如何利用Stopwatch比较精确的测试算法运算时间
- c#中的一点小细节