#高精度計時器代碼測試
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; } } } }
|