Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools

High-precision timing with the QueryPerformanceCounter API function

Total Hit ( 4878)

Rate this article:     Poor     Excellent 

 Submit Your Question/Comment about this article

Rating


 


While VB Timer functions is sufficiently precise for most tasks, it doesn't provide the highest possible resolution most modern computer can provide. If your hardware supports high-resolution counters, you can do a much better job with a pair of API functions:

Click here to copy the following block
Private Type LARGE_INTEGER
  lowpart As Long
  highpart As Long
End Type
Private Declare Function QueryPerformanceFrequency Lib "kernel32" Alias _
  "QueryPerformanceFrequency" (lpFrequency As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" Alias _
  "QueryPerformanceCounter" (lpPerformanceCount As LARGE_INTEGER) As Long

You should call QueryPerformanceFrequency once, at the beginning of your program, to retrieve the internal frequency of the high-res timer, that is the number of ticks it provides each second. Then you can call QueryPerformanceCounter as many times as you wish: each call returns the value of the internal counter. For example, you retrieve the value of the counter at the beginning and the end of a piece of code you want to time, and if you subtract the former from the latter value you get the number of ticks elapsed in the meantime. Converting this value into seconds only requires that you divide it by the frequency found previously.
The problem with these APIs is that VB doesn't support large integers, that is 64-bit integers. This means that you are compelled to do process the high and low halves of those large numbers separatedly, which amounts to a lot of code and overhead.

Fortunately there is a neat trick that solves this problem quite nicely. Instead of using LARGE_INTEGERS, you can use Currency variables. After all, Currency values are plain 64-bit integers that VB scales by a factor of 10,000 any time you assign a value to them and the read it back. To use Currency variables instead of LARGE_INTEGER values you must use aliased functions:

Click here to copy the following block
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

Here's a piece of code that illustrates how to use these two API functions:

Click here to copy the following block
Private Sub Command1_Click()
  Dim frequency As Currency
  Dim startTime As Currency
  Dim endTime As Currency
  Dim result As Double
  
  ' get the frequency counter
  ' return zero if hardware doesn't support high-res performance counters
  If QueryPerformanceFrequencyAny(frequency) = 0 Then
    MsgBox "This computer doesn't support high-res timers", vbCritical
    Exit Sub
  End If
  
  ' start timing
  QueryPerformanceCounterAny startTime
  
  ' put here the code to be timed, for example...
  Dim i As Long
  For i = 1 To 1000000
  Next

  ' end timing  
  QueryPerformanceCounterAny endTime
  
  ' note that both dividend and divisor are scaled
  ' by 10,000, so you don't need to scale the result
  result = (endTime - startTime) / frequency
  
  ' show the result
  MsgBox result
End Sub

As you see, in this particular case you don't even need to take the 10,000 scaling factor into account, because both operands of the division near the end of the procedure are scaled by the same factor, so you can (and must) ignore it.



Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.