Library tutorials & articles
Performance Issues
- Introduction
- Memory
- Compiling
- Increasing Speed
- The magic $
- Measuring Performance
- SQL vs DAO
Measuring Performance
When you make changes to your program, hoping to make it run faster, you need a way to accurately measure the time between certain events. You can do this by using the QueryPerformanceCounter and QueryPerformanceFrequency to measure this. As an example, lets use the following code:
Private Declare Function QueryPerformanceCounter Lib "kernel32"
(lpPerformanceCount As Any) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32"
(lpFrequency As Any) As Long
'// timer frequency
Dim secFreq As Currency
Private Sub cmdTimeIt_Click()
Dim sec As Currency, secOut As Currency
Dim I As Long
'// start the timer
ProfileStart sec
'// do something
For I = 0 To 1000000
DoEvents
Next
ProfileStop sec, secOut
MsgBox secOut
End Sub
Sub ProfileStart(secStart As Currency)
'// if we do not have the timer frequency, then get it
If secFreq = 0 Then QueryPerformanceFrequency secFreq
'// get the current value
QueryPerformanceCounter secStart
End Sub
Sub ProfileStop(secStart As Currency, secTiming As Currency)
'// get the time passed
QueryPerformanceCounter secTiming
If secFreq = 0 Then
'// there is no high-resolution timer
available.
secTiming = 0
Else
'// calculate the time taken from
the start value, finish value, and the timer frequency.
secTiming = (secTiming - secStart)
/ secFreq
End If
End Sub
As you can see, we pass the ProfileStart procedure an empty Currency variable (sec) to hold the start value. When the code you want to run is finished, call the ProfileStop procedure with the start value (sec), and another empty Currency variable (secOut). The value contained in secOut is the time taken. You usually get the time taken, accurate to the nearest microsecond. As you can see, this is invaluable when trying to see the changes in performance as you change your code.
We can also use GetTickCount API for Measuring Performance. The following code
gives you an example.
Private Sub TimeOperation()
Dim I as Long
Dim x as Long
Dim Y as Long
Dim Z as Double
X = GetTickCount()
For I = 0 to 1000000
Z = SIN(i)
Next I
Y = GetTickCount - x
MsgBox "This operation takes " & Y/1000 &
" seconds to finish'
End Sub
Thanks to Georgi Ganchev for this tip.
For more information on this, and other methods for timing code, search for 'HOWTO: Use QueryPerformanceCounter to Time Code' in the MSDN library.
Related articles
Related discussion
-
Run-time error '91'
by converter2009 (1 replies)
-
VB6 Runtime error 381 subsript out of range Error
by Uncle (2 replies)
-
passing and reading parameters from using Shell
by jigartoliya (0 replies)
-
Convert C++ code to VB6
by mawcot (4 replies)
-
listbox scrollbar
by Dennijr (10 replies)
Related podcasts
-
Christian Beauclair
14 mai 2008 (�mission #0074) ::.Christian Beauclair: Stratégies de migration VB6 vers .NET Nous discutons avec Christian Beauclair des stratégies de migration VB6 vers .NET. Entre autres, nous discutons comment utiliser le "VB 6 Code Advisor" et le "Interop Forms Toolkit" pour ajouter la puiss...
And once again a greate article by james!
This posting is specifically a response to James Cowleys suggestion that using ByVal is quicker than using ByRef. This is only true when calling an out-of-process server (i.e. and ActiveX EXE). VB is designed to pass all parameters ByRef, which means that everything is passed as a 32-bit pointer. When passing ByVal VB copies the contents of the parameter into temporary space and then passes a 32-bit pointer to the temporary space. This means that, counter-intuitively, it is slower passing a long ByVal than it is ByRef.
When calling an out-of-process server OLE must marshal a copy of your parameter into the address space of the routine you are calling and then, if it is ByRef, copy it back afterwards. This is probably the only occasion that passing ByRef is slower.
Generally ByVal should be reserved for occasions when the routine is going to change the contents of the variable and the calling routine will be affected by the change. At the very least use ByRef for all strings and variants.
This thread is for discussions of Performance Issues.