#高精度计时器代码测试
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test { class Program { static void Main(string[] args) { const long count = 1000000; HiPerfTimer time; time = new HiPerfTimer(); time.Start(); for (int i = 0; i < count; i++) { i++; } time.Stop(); Console.WriteLine("It Spends: =" + time.Duration + "\n"); Console.ReadKey(); } } }
直接从 C# 调用 DLL 导出
若要声明一个方法使其具有来自 DLL 导出的实现,请执行下列操作:
使用 C# 关键字 static 和 extern 声明方法。
将 DllImport 属性附加到该方法。DllImport 属性允许您指定包含该方法的 DLL 的名称。通常的做法是用与导出的方法相同的名称命名 C# 方法,但也可以对 C# 方法使用不同的名称。
还可以为方法的参数和返回值指定自定义封送处理信息,这将重写 .NET Framework 的默认封送处理。
精确的时间计量方法在某些应用程序中是非常重要的。常用的 Windows API 方法 GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,很不精确。
故而,我们要另外寻找一种方法来精确测量时间。
Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。另一方面来说,在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。
第一个函数 QueryPerformanceCounter() 查询任意时刻高精度计数器的实际值。第二个函数 QueryPerformanceFrequency() 返回高精度计数器每秒的计数值。为了获得某一代码段经历的时间,你需要获得代码段开始前和结束后这两个计时时刻的高精度计数器实际值。这两个值的差指出了代码段执行所经历的时间。
然后通过将差除以每秒计数值(高精度计时器频率),就可以计算经过的时间了。
duration = (stop - start) / frequency
经过时间 = (停止时间 - 开始时间) / 频率
需要关于 QueryPerformanceCounter 和 QueryPerformanceFrequency 的更多信息,请参阅 MSDN 文档。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;//DllImport using System.ComponentModel;//Win32Exception using System.Text.RegularExpressions; //RegexOptions using Microsoft.VisualBasic; //CompareMethod namespace Test { internal class HiPerfTimer { [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter(ref long lpPerformanceCount); [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(ref long lpFrequency); private long startTime, stopTime; private long freq; // the counter frequency private bool running; public HiPerfTimer() { startTime = 0; stopTime = 0; if (QueryPerformanceFrequency(ref freq) == false) throw new Win32Exception(); // high-performance counter not supported running = false; } public bool Running { get { return running; } } /// /// Start the timer, and save the start time. /// public void Start() { QueryPerformanceCounter(ref startTime); running = true; } /// /// Stop the timer, and record the stop time. /// public void Stop() { QueryPerformanceCounter(ref stopTime); running = false; } /// /// The duration of the timer, in seconds. /// public double Duration { get { return (double)(stopTime - startTime) / (double)freq; } } } }
|