Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: Visual Basic
Expertise: Advanced
Feb 3, 1999

Use This Higher-Resolution Stopwatch

Use this code to create a class called HiResTimer:
 
'The number is codified as HighPart*2^32+LowPart
Private Type LARGE_INTEGER
	LowPart As Long
	HighPart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib _
	"kernel32" (lpPerformanceCount As LARGE_INTEGER) _
	As Long
Private Declare Function QueryPerformanceFrequency Lib _
	"kernel32" (lpFrequency As LARGE_INTEGER) As Long

Private m_TicksPerSecond As Double
Private m_LI0 As LARGE_INTEGER
Private m_LI1 As LARGE_INTEGER

Friend Sub Class_Initialize()
	Dim LI As LARGE_INTEGER

	If QueryPerformanceFrequency(LI) <> 0 Then
		m_TicksPerSecond = LI2Double(LI)
	Else
		m_TicksPerSecond = -1
	End If
End Sub

Friend Property Get Resolution() As Double
	Resolution = 1# / m_TicksPerSecond
End Property

Friend Sub EnterBlock()
	QueryPerformanceCounter m_LI0
End Sub

Friend Sub ExitBlock()
	QueryPerformanceCounter m_LI1
End Sub

Friend Property Get ElapsedTime() As Double
	Dim EnterTime As Double, ExitTime As Double

	EnterTime = LI2Double(m_LI0) / m_TicksPerSecond
	ExitTime = LI2Double(m_LI1) / m_TicksPerSecond
	ElapsedTime = ExitTime - EnterTime
End Property

Friend Function LI2Double(LI As LARGE_INTEGER) As Double
	Dim Low As Double
	Const TWO_32 = 4# * 1024# * 1024# * 1024#

	Low = LI.LowPart
	If Low < 0 Then Low = Low + TWO_32
		'Now Low is in the range 0...2^32-1

		LI2Double = LI.HighPart * TWO_32 + Low
End Function
Here's an example of the HiResTimer in use:
 
Dim hrt As HiResTimer, d As Double
Set hrt = New HiResTimer
Debug.Assert hrt.Resolution > 0
MsgBox "Resolution [usecs]:" & hrt.Resolution * 1000000#

hrt.EnterBlock
hrt.ExitBlock
MsgBox "Call overhead [usecs]:" & hrt.ElapsedTime * _
	1000000#

hrt.EnterBlock
d = 355# / 113#
hrt.ExitBlock

MsgBox "Elapsed Time [usecs]:" & hrt.ElapsedTime * _
	1000000#
Believe it or not, you can time even native-compiled code division. For more information, look at the MSDN Library description of the kernel APIs used here. On x86 architectures, resolution is better that 1 microsecond. Be careful, however, of trusting single instance timings, as you'll find the "resolution" of this performance counter varies over time. In fact, the overhead of simply calling QueryPerformanceCounter in VB is quite a measurable time period itself.

Although you can time single operations, you're still better off averaging the time required for hundreds or thousands of similar operations.

Alessandro Coppo
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date