measuring the execution time of commands (VB6 API & examples)

Posted at


The two APIs that are explained in this article are:
1. timeGetTime (winmm.dll).
2. QueryPerformanceCounter (kernel32.dll).



example #1:
using timeGetTime, timeBeginPeriod and timeEndPeriod.
(API of winmm.dll)

Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub test_timeGetTime()
    Dim ltime As Long
    
    Dim api_overhead As Long
    Call timeBeginPeriod(1): ltime = timeGetTime
    Call timeEndPeriod(1): api_overhead = timeGetTime - ltime
    
    
    Call timeBeginPeriod(1): ltime = timeGetTime
    
    'work....start.\\
    Sleep 5313
    'work.... done./
    
    Call timeEndPeriod(1): ltime = timeGetTime - ltime
    
    MsgBox "benchmark = " & CStr((ltime - api_overhead)) & " milliseconds." & vbNewLine & _
           "(" & Format((ltime - api_overhead) / 1000, "00.00") & " seconds).", vbInformation Or vbOKOnly, "example #1: using timeGetTime"
End Sub


example #2:
using QueryPerformanceCounter and QueryPerformanceFrequency.
(API of kernel32.dll)

Private Declare Function QueryPerformanceCounter Lib "kernel32.dll" (lpPerformanceCount As Currency) As Boolean
Private Declare Function QueryPerformanceFrequency Lib "kernel32.dll" (lpFrequency As Currency) As Boolean

Private Sub test_QueryPerformanceFrequency()
    Dim timeStart As Currency
    Dim timeFinish As Currency
    Dim freq As Currency
    Dim overhead As Currency
    
    If (QueryPerformanceCounter(timeStart)) Then
        QueryPerformanceCounter timeFinish
        If (QueryPerformanceFrequency(freq)) Then
            overhead = timeFinish - timeStart ' determine API call overhead
            
            QueryPerformanceCounter timeStart     ' time loop
            
            'work....start.\\
            Dim i As Long
            Dim a As Long
            For i = 1 To 100
                a = a + i
                DoEvents
            Next i
            'work.... done./
    
            QueryPerformanceCounter timeFinish   ' time loop
            
            MsgBox "Takes " & Format(((timeFinish - timeStart - overhead) / freq), "000.00000000") & " seconds.", vbInformation Or vbOKOnly, "Timing using high-resolution performance counter"
        Else
            MsgBox "the installed hardware does not support a high-resolution performance counter, the function fails.", vbExclamation, "Error " & CStr(Err.LastDllError)
        End If
    Else
        MsgBox "the installed hardware does not support a high-resolution performance counter, the function fails.", vbExclamation, "Error " & CStr(Err.LastDllError)
    End If
End Sub


Note: API calls made by timeGetTime and QueryPerformanceCounter takes some time to execute, so a rough estimate is calculated first and saved in a overhead variable, later to be subtracted from the total time. suggested by Microsoft's example (see MSDN links on top of the post).

Note: Sometimes QueryPerformanceCounter is overused, or misuse, the precision degree of QueryPerformanceCounter is undue, it is mostly used for graphics calculation. It is recommended to use timeGetTime with the minimal frame of timeBeginPeriod and timeEndPeriod as suggested in
http://msdn.microsoft.com/en-us/library/dd757629(VS.85).aspx.