I would like to be able to determine how long a process takes in milliseconds. The time functions in VB only appear to deal with times down to seconds. Are there API functions I can use to compare two times in milliseconds?
The timer is much easier to work with and why write all that extra API.
The Timer() function also is based on the 1 clock tick which is equal to 55 milliseconds.
You just need to make sure you define your variables as doubles, as the above from Jon4747 applies, in order to get the correct decimal value returned.
The same with the Now() function. To get a fraction of a second using now()
Dim s As Double 'Start
Dim e As Double 'End
Dim i As Long
s=now
'<Some Code>
For i = 1 To 10000000
Next i
e=now
Debug.Print e-s
All that extra API code is the one line of function declaration.
I think it all boils down to the degree of precision. Running the following code:
For Index = 1 To 1000
TimerValue(Index) = Timer
TickValue(Index) = GetTickCount
Next Index
Set TimerChanges = New Collection
Set TickChanges = New Collection
For Index = 2 To 1000
If (TimerValue(Index) <> TimerValue(Index - 1)) Then
TimerChanges.Add Trim(Index) & ":" & TimerValue(Index)
End If
If (TickValue(Index) <> TickValue(Index - 1)) Then
TickChanges.Add Trim(Index) & ":" & TickValue(Index)
End If
Next Index
I then recorded when the result changed. The following chart show when the changes occurred for the first three runs.
Don't waste all your time, people. The Timer function is only accurate to hundreths of a second. The apparant additional accuracy is actually caused by the casting from one floating type to another doesn't help either. Don't believe it? Let's illustrate:
Dim lp As Single
For lp = 0 To 0.99 Step 0.01
Debug.Print CDbl(lp)
Next
I'd go with CajunCenturion's solution (although, as stated you cannot guarantee better than about 55ms accuracy from it. If you want better resolution than this, consider using the QueryPerformanceFrequenncy and QueryPerformance counter API functions, which provide microsecond accuracy)
Here is the complete code for an accurate timer class using API functions. You can start, stop and reset the timer. It is accurate to about 10 microseconds (depending on processor). You can't use it like a timer control to generate interrupts, but it's far better than using the system tick timer for timing processes.
Once you've used this method for a bit you won't want to go back!
Put this in as a class module and then create as many independent timers as you need.
Private Declare Function QueryPerformanceFrequencyAny Lib "kernel32" Alias _
"QueryPerformanceFrequency" (lpFrequency As Any) As Long
Private Declare Function QueryPerformanceCounterAny Lib "kernel32" Alias _
"QueryPerformanceCounter" (lpPerformanceCount As Any) As Long
Private mStartTime As Currency
Private mEndTime As Currency
Private mTotalTime As Double
Private mFrequency As Currency
Private mRunning As Boolean
Private mDuration As Double
Private Sub Class_Initialize()
' measure the frequency of the counter-timer
' ensure the computer is compatible
If QueryPerformanceFrequencyAny(mFrequency) = 0 Then
Err.Raise 1001, , "Hardware out of date!"
mFrequency = 0
Exit Sub
End If
End Sub
Public Sub StartTimer()
QueryPerformanceCounterAny mStartTime
mRunning = True 'used in Duration property
End Sub
Public Sub StopTimer()
mTotalTime = mDuration 'transfer cumulative time so far to module-level variable
mRunning = False 'no longer running
End Sub
Public Sub ResetTimer()
If mRunning Then
StartTimer
End If
mTotalTime = 0# 'only used when in stopped condition
End Sub
Public Property Get Duration() As Double
Dim Interval As Double
If mFrequency = 0 Then
Err.Raise 1002, , "Accurate timer object not initialised"
Duration = 0
Exit Property
End If
If mRunning Then
QueryPerformanceCounterAny mEndTime 'get a new endtime
Interval = CDbl(mEndTime - mStartTime) / mFrequency
mDuration = mTotalTime + Interval 'the stored total so far plus the new addition
Else
mDuration = mTotalTime 'not running - return cumulative
End If
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.