• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

一个C#获取高精度时间类(调用APIQueryP*)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这两个API来实现。

QueryPerformanceCounter 最小分辨率: 1/1193182 秒
API 开销: 1.92761875388667E-05 秒

多个语句执行之前 GetTickCount 或 timeGetTime 记录的更改。实际的循环数因操作系统正在执行的后台任务而异。
另一方面,QueryPerformanceCounter 更改,该值指示在高分辨率的时间中其用途的连续 API 调用之间的值。在这种情况下,分辨率是一个 microsecond 的顺序。因为系统依赖于分辨率,不存在,它测量标准单元。您必须通过确定的秒数经过 QueryPerformanceFrequency 划分不同之处。在上述情况只调用 API 的开销是关于 19 微秒为单位)。这将不得不上进行减法运算.

//引用的命名空间 using System.Runtime.InteropServices; using System.Security; //////////////////////////// /// <summary> /// 定义一个高精度的时间类 /// </summary> public class Timer { #region private members private long ticksPerSecond = 0; private long elapsedTime = 0; private long baseTime = 0; #endregion #region windows API /// <summary> /// 获取时间的精度 /// </summary> /// <param name="PerformanceFrequency"></param> /// <returns></returns> [SuppressUnmanagedCodeSecurity] [DllImport("kernel32")] static private extern bool QueryPerformanceFrequency(ref long PerformanceFrequency); /// <summary> /// 获取时间计数 /// </summary> /// <param name="PerformanceCount"></param> /// <returns></returns> [SuppressUnmanagedCodeSecurity] [DllImport("kernel32")] static private extern bool QueryPerformanceCounter(ref long PerformanceCount); #endregion #region constructors /// <summary> /// new /// </summary> public Timer() { // Use QueryPerformanceFrequency to get frequency of the timer if (!QueryPerformanceFrequency(ref ticksPerSecond)) throw new ApplicationException("Timer: Performance Frequency Unavailable"); Reset(); } #endregion #region public methods /// <summary> /// 重置时间相关计数器 /// </summary> public void Reset() { long time = 0; QueryPerformanceCounter(ref time); baseTime = time; elapsedTime = 0; } /// <summary> /// 获取当前与最近一次 reset 时间差 /// </summary> /// <returns>The time since last reset.</returns> public double GetTime() { long time = 0; QueryPerformanceCounter(ref time); return (double)(time - baseTime) / (double)ticksPerSecond; } /// <summary> /// 获取当前系统的时间 ticks 数 /// </summary> /// <returns>The current time in seconds.</returns> public double GetAbsoluteTime() { long time = 0; QueryPerformanceCounter(ref time); return (double)time / (double)ticksPerSecond; } /// <summary> /// 获取此次与上次调用此方法的两次时间差 /// </summary> /// <returns>The number of seconds since last call of this function.</returns> public double GetElapsedTime() { long time = 0; QueryPerformanceCounter(ref time); double absoluteTime = (double)(time - elapsedTime) / (double)ticksPerSecond; elapsedTime = time; return absoluteTime; } #endregion }

调用代码举例:
Timer t = new Timer();
double time = t.GetAbsoluteTime();
t.GetElapsedTime();
t.Reset();
t.GetTime();

////////////////////////////////////////////////////

在某些计算机上,由 QueryPerformanceFrequency 返回的结果将作为 CPU 的时钟速度。在处理器运行速度超过 2.1 GHz 的计算机上,该频率值需要至少 32 位的精度。某些程序将 QueryPerformanceFrequency 的结果用作经过签署的整数值,该值只有 31 位精度并带有符号标志。这些程序在这些较快的 CPU 上无法正确运行。要避免出现此问题,程序必须使用由 QueryPerformanceFrequencyQueryPerformanceCounter 返回的所有64 位。
有关超线程技术的更多信息,请访问下面的 Intel Web 站点:

http://cedar.intel.com/cgi-bin/ids.dll/topic.jsp?catCode=CDN


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
测试C#类型转换效率问题发布时间:2022-07-10
下一篇:
C#窗体内控件大小随窗体等比例变化发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap