日期:2014-05-18  浏览次数:20717 次

「翻译」C# 中的高性能计时器(Daniel Strigl著,野比译)
嗯,这篇是存档,避免被时间冲走。

嗯,万恶的我又来刷版了。

--------------

这是2008年翻译的奥地利人Daniel Strigl的Hi-performance Timer in C#一文。

还是那句话,请尽量保留版权,这些老外的文章可以随便用,但都是有条件的,参见CPOL


先上源码

点我下载源码

p.s. 怪事:我发的资源都一分没收,为啥我的下载分会有500多分呢?

---------------------下面是正文了--------------------

[奥地利]Daniel Strigl 著 野比 译

来源:http://www.codeproject.com




简介

精确的时间计量方法在某些应用程序中是非常重要的。常用的 Windows API 方法 GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,很不精确。

故而,我们要另外寻找一种方法来精确测量时间。

Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。另一方面来说,在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。

第一个函数 QueryPerformanceCounter() 查询任意时刻高精度计数器的实际值。第二个函数 QueryPerformanceFrequency() 返回高精度计数器每秒的计数值。为了获得某一代码段经历的时间,你需要获得代码段开始前和结束后这两个计时时刻的高精度计数器实际值。这两个值的差指出了代码段执行所经历的时间。

然后通过将差除以每秒计数值(高精度计时器频率),就可以计算经过的时间了。

duration = (stop - start) / frequency
经过时间 = (停止时间 - 开始时间) / 频率

需要关于 QueryPerformanceCounter 和 QueryPerformanceFrequency 的更多信息,请参阅 MSDN 文档。

代码

下面的类实现了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函数的功能。

C# code
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;

namespace Win32
{
    internal class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(
            out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(
            out long lpFrequency);

        private long startTime, stopTime;
        private long freq;

        // 构造函数
        public HiPerfTimer()
        {
            startTime = 0;
            stopTime  = 0;

            if (QueryPerformanceFrequency(out freq) == false)
            {
                // 不支持高性能计数器
                throw new Win32Exception();
            }
        }

        // 开始计时器
        public void Start()
        {
            // 来让等待线程工作
            Thread.Sleep(0);

            QueryPerformanceCounter(out startTime);
        }

        // 停止计时器
        public void Stop()
        {
            QueryPerformanceCounter(out stopTime);
        }

        // 返回计时器经过时间(单位:秒)
        public double Duration
        {
            get
            {
                return (double)(stopTime - startTime) / (double) freq;
            }
        }
    }
}


使用这个类很简单。只需要创建一个 HiPerfTimer 的实例,然后调用 Start() 开始计时,Stop() 停止计时。要获得经过的时间,调用 Duration() 函数即可。

参考下面的例子。

C# code
HiPerfTimer pt = new HiPerfTimer();     // 创建新的 HiPerfTimer 对象
pt.Start();                             // 启动计时器
Console.WriteLine("Test\n");            // 需要计时的代码
pt.Stop();                              // 停止计时器
Console.WriteLine("Duration: {0} sec\n", 
     pt.Duration); // 打印需要计时部分代码的用时


下面的图片是该例子在我系统上的输出。





--------野比见解--------

由于这个计时器精度太高,我想除了工控或采集等项目,其他地方应该是用不到的吧?

------解决方案--------------------
平时 stopwatch 够用了
jf
------解决方案--------------------
感谢分享~~~~~~~~
------解决方案--------------------
探讨

平时 stopwatch 够用了
jf

------解决方案--------------------
难道这个精度顶的上原子钟的纳秒么,后面位数又不是精确的