文章編號: 172338 - 上次校閱: 2007年1月20日 - 版次: 3.3

如何使用 QueryPerformanceCounter 時間程式碼,

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

當程式碼,以找出效能瓶頸的預存時間,您想要使用系統所提供的最高解析度計時器。本文將告訴您,如何使用 QueryPerformanceCounter 函式,將時間應用程式的程式碼。

其他相關資訊

由作業系統會提供不同的精確度的幾個計時器:
Function                 Units                      Resolution
---------------------------------------------------------------------------
Now, Time, Timer         seconds                    1 second
GetTickCount             milliseconds               approx. 10 ms
TimeGetTime              milliseconds               approx. 10 ms
QueryPerformanceCounter  QueryPerformanceFrequency  same
				
如果您的系統支援高解析度的計數器,您可以使用 QueryPerformanceCounter 和 QueryPerformanceFrequency 執行高解析度的計時。

下列範例程式碼會比較不同的計數器:

警告: 任何使用您程式碼本文中所提供的是,請自行負擔相關的風險。Microsoft 提供 「 現狀 」 這個程式碼並不提供任何種類明示或默示包括但不是限於適售性以及適合某特定用途之默示擔保責任。

逐步程序

  1. 下列程式碼輸入一個模組中。如果您輸入到類別、 表單或報表模組,請宣告私用。
           Option Explicit
    
          Declare Function QueryPerformanceCounter Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function QueryPerformanceFrequency Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function GetTickCount Lib "Kernel32" () As Long
          Declare Function timeGetTime Lib "winmm.dll" () As Long
    
          Sub Test_Timers()
          Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
          Dim Count1 As Long, Count2 As Long, Loops As Long
          '
          ' Time QueryPerformanceCounter
          '
            If QueryPerformanceCounter(Ctr1) Then
              QueryPerformanceCounter Ctr2
              Debug.Print "Start Value: "; Format$(Ctr1, "0.0000")
              Debug.Print "End Value: "; Format$(Ctr2, "0.0000")
              QueryPerformanceFrequency Freq
              Debug.Print "QueryPerformanceCounter minimum resolution: 1/" & _
                          Freq * 10000; " sec"
              Debug.Print "API Overhead: "; (Ctr2 - Ctr1) / Freq; "seconds"
            Else
              Debug.Print "High-resolution counter not supported."
            End If
          '
          ' Time GetTickCount
          '
            Debug.Print
            Loops = 0
            Count1 = GetTickCount()
            Do
              Count2 = GetTickCount()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "GetTickCount minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          '
          ' Time timeGetTime
          '
            Debug.Print
            Loops = 0
            Count1 = timeGetTime()
            Do
              Count2 = timeGetTime()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "timeGetTime minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          End Sub
    						
  2. 從 [偵錯/即時運算] 視窗執行函式。您的輸出看起來應該類似下列:
    啟動值: 3516284.3498
    結束值: 3516284.3521
    QueryPerformanceCounter 最小解析度: 1/1193182 秒
    API 負荷: 1.92761875388667E-05 秒

    GetTickCount 最小解析度: 10 ms
    花了 650 迴圈

    timeGetTime 最小解析度: 10 ms
    花了 1565年迴圈
多個陳述式執行之前 GetTickCount 或是 timeGetTime 記錄變更。視背景工作執行作業系統而異迴圈實際數目。

在另一方面,QueryPerformanceCounter 變更連續的 API 呼叫指出在高解析度的計時其可用性之間的值。解決方式在這種情況下是一微秒的順序。因為解析度系統相關沒有標準的單位,它會測量。您必須差異除以 QueryPerformanceFrequency 來決定的已耗用秒數。在上述情況的只呼叫 API 負荷是約 19 微秒數。這就必須時的預存時間其他程式碼,如下所示減去:
   Private Sub Time_Addition()
   Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
   Dim Overhead As Currency, A As Long, I As Long
     QueryPerformanceFrequency Freq
     QueryPerformanceCounter Ctr1
     QueryPerformanceCounter Ctr2
     Overhead = Ctr2 - Ctr1        ' determine API overhead
     QueryPerformanceCounter Ctr1  ' time loop
     For I = 1 To 100
       A = A + I
     Next I
     QueryPerformanceCounter Ctr2
     Debug.Print "("; Ctr1; "-"; Ctr2; "-"; Overhead; ") /"; Freq
     Debug.Print "100 additions took";
     Debug.Print (Ctr2 - Ctr1 - Overhead) / Freq; "seconds"
   End Sub
				
範例輸出:
(3630876.6256-3630876.6388-0.0013) / 119.3182
100 加入項目所花費的 9.97333181358753E-05 秒
注意: 由於貨幣變數用,將傳回值是 10000 時間小於實際的計數器。因為秒數計算會涉及除法運算,取消這項因素。

?考

Microsoft 開發 o 人 h 員 ? 工 u 具 ? 網路 ; 主題: timeGetTime GetTickCount QueryPerformanceCounter QueryPerformanceFrequency

這篇文章中的資訊適用於:
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Control Creation Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic 4.0 32-Bit Enterprise Edition
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft Access 95 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 95 Standard Edition
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
關鍵字:?
kbmt kbhowto kbprogramming KB172338 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:172338? (http://support.microsoft.com/kb/172338/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。