嗯,萬惡的我又來刷版了。
--------------
這是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 函數的功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
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() 函數即可。
參考下面的例子。
1
2
3
4
5
6
|
HiPerfTimer pt = new HiPerfTimer(); // 創建新的 HiPerfTimer 對象 pt.Start(); // 啓動計時器 Console.WriteLine( "Test\n" ); // 需要計時的代碼 pt.Stop(); // 停止計時器 Console.WriteLine( "Duration: {0} sec\n" , pt.Duration); // 打印需要計時部分代碼的用時 |
下面的圖片是該例子在我係統上的輸出。
--------野比見解--------
由於這個計時器精度太高,我想除了工控或採集等項目,其他地方應該是用不到的吧?