High-precision timing with the QueryPerformanceCounter API function

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:

Private Type LARGE_INTEGER    lowpart As Long    highpart As LongEnd TypePrivate Declare Function QueryPerformanceFrequency Lib "kernel32" Alias _    "QueryPerformanceFrequency" (lpFrequency As LARGE_INTEGER) As LongPrivate 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:

Private Declare Function QueryPerformanceFrequencyAny Lib "kernel32" Alias _    "QueryPerformanceFrequency" (lpFrequency As Any) As LongPrivate 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:

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 resultEnd 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.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

6 Tips for Setting Up a Decentralized Exchange

6 Tips for Setting Up a Decentralized Exchange

There’s no doubt that cryptocurrency is a complex and divisive topic in the modern financial landscape. There are those who are convinced that it’s nothing more than a bubble, but both who are well-informed are able to see the ways in which cryptocurrency can help them both build their fortune

user experience with someone on their phone

5 Ways to Improve Your Customers’ User Experience

They say you can’t judge a book by its cover, but just because they say that doesn’t mean it’s true. Consider how often you choose one sort of product over another just because it appeals to you. Then think about how often you’ve stopped using something because, simply put, it

How to Manage Your Finances after Buying a Home

How to Manage Your Finances after Buying a Home

Buying a home is a milestone in the journey of life – it’s one way to invest your money and create lasting memories. Now you know everything about a home purchase, home mortgage, and what is a conventional 97 loan but do you know what’s next after you sign the

Windows Logging is one of the vital aspects of any Windows system administration. However, it is mostly overlooked until the system develops a problem. This is because logs contain important information needed to troubleshoot and resolve system issues.

The Fundamentals of Windows Logging

Windows Logging is one of the vital aspects of any Windows system administration. However, it is mostly overlooked until the system develops a problem. This is because logs contain important information needed to troubleshoot and resolve system issues. Without it, tech experts might find it difficult to track a computer’s

Interstitial Ads: Best Practices for Successful Campaigns

Interstitial Ads: Best Practices for Successful Campaigns

Interstitial Ads: Best Practices for Successful Campaigns Interstitial ads are full-screen advertisements that appear to grasp the attention of on-site prospects, creating opportunities for brands seeking effective ways to communicate their proposition of value. With such an attention-grabbing format and high-impact visuals, it’s no wonder why interstitial advertising is proving