|
-
Jun 8th, 2004, 10:50 AM
#1
Thread Starter
Frenzied Member
speed question
I have a small procedure that is being run VERY often (@5Hz) and it currently resides in a module outside of the form that calls it. Would it be faster if I moved it into the code of the form?
-
Jun 8th, 2004, 10:56 AM
#2
Yes, procedure calls take time. Any parameters need to be passed/copied, and the code flow needs to jump (and jump back again afterwards).
I once improved the speed of some code using this method, it went from doing 200 iterations per second to over 2000. (results will vary depending on the code involved).
Obviously it may mean having to write the same code in more than one place, but if you are after speed it is an appropriate thing to do.
-
Jun 8th, 2004, 11:04 AM
#3
A call is a call is a call. Doesn't matter where it is (unless it's in a separate object such as a dll or some such). If it's in a code module in the same project, moving it isn't going to help. Maybe what you should do is take a second look at it and see if there is a way to optimize it to run better.
TG
-
Jun 8th, 2004, 11:24 AM
#4
T.G. is right - I meant to say that you should put the code inline (ie: dont have it as a procedure)... browser crashed mid post tho 
There are many ways of optimising code, but it all depends on what you are doing, and how you are doing it. If you post the code (and an explanation of what it needs to do) we can give better advice.
Putting procedures inline does give a speed boost, but it may be more hassle than it is worth, as you can easily get un-readble and hard-to-maintain code.
-
Jun 8th, 2004, 11:48 AM
#5
Thread Starter
Frenzied Member
Here is the code:
VB Code:
Public Sub GetStepTime()
Dim lngTemp As Long
On Error GoTo GetStepTime_Error
If NEWSTEP Then
STARTSTEPTIME = GetTickCount
lngTemp = frmMain.flxSP2.CellText(STEPNUM, 4)
FULLSTEPTIME = lngTemp * 1000
NEWSTEP = False
Else
CURSTEPTIME = GetTickCount
If CURSTEPTIME - STARTSTEPTIME > FULLSTEPTIME Then
NEWSTEP = True
STEPNUM = STEPNUM + 1
End If
End If
On Error GoTo 0
Exit Sub
GetStepTime_Error:
LogError Err.Number, Err.Description, Err.Source, False, "GetStepTime of Module basDurb"
End Sub
It is checking to see if the time for a step in the program has expired. I have a timer on my main form that is set to 200ms that calls it. It seems to be working ok so far, but I still have a lot of functionality to build into the system (limit checking, data logging, value display, etc) and I want to make sure this runs as clean as possible.
One thing that I was going to do to try and optomize it is to put the times into an array so that I'm not reading the value from a control on every pass.
-
Jun 8th, 2004, 11:58 AM
#6
Timer controls are not very good - apparently they are only accurate to about 70ms (that's up to 35% out with 200ms). They also have various other 'issues', as detailed in many posts on this forum.
An API timer would be a far more accurate method (if you are concerned with a specific frequency, this can only be a good thing).
You are right that reading from a control is slow, what is the reason for having it? (I don't understand from what you have already posted).
-
Jun 8th, 2004, 11:58 AM
#7
If you really want to optimize for speed, replace 1000, 4 and 1 with constants.
BTW, you also don't need the On error Goto 0 line.
-
Jun 8th, 2004, 12:13 PM
#8
Thread Starter
Frenzied Member
Originally posted by si_the_geek
An API timer would be a far more accurate method (if you are concerned with a specific frequency, this can only be a good thing).
You are right that reading from a control is slow, what is the reason for having it? (I don't understand from what you have already posted).
Can you recommend a good API timer? Should I use the SetTimer API? The only reason I was reading the value from a control is that I was going to let the user change the step time while running the test.... however, this is not necessary and would be far from the norm, so I guess reading it from an array would work just as easily.
Martin, I will change those to constants, thank you.
-
Jun 8th, 2004, 12:22 PM
#9
Thread Starter
Frenzied Member
Ok, another question... each "step" I have been referring to has 4 parts and I'll have to refer to each part when the step is changes, so I might as well load them all into arrays..... so would it be faster to have a UDT of arrays, a 2 dimensional array, or 4 seperate arrays? The 4th part of each step will be hammered on much more than the other parts.
In other words, I'll be checking the 4th element to see if that much time has passed, and then I'll be loading the other 3 parts for the next step when that time has expired.
Is this making sense?
-
Jun 8th, 2004, 12:25 PM
#10
Martin,
I was not aware that "literal" values in VB were not compiled into constants in the .EXE. Are you saying that having the value 1 in a math equation is slower than using a constant that is assigned to the value 1?
Why?
-
Jun 8th, 2004, 03:18 PM
#11
Fanatic Member
^ What he said. That would seem idiotic if it's the case.
-
Jun 8th, 2004, 06:18 PM
#12
Thread Starter
Frenzied Member
I would also like elaboration on this topic.
-
Jun 8th, 2004, 06:23 PM
#13
All I can do is to quote from MSDN which says under the Optimizing for Speed topic
Use Constants Whenever Possible
Using constants makes your application run faster. Constants also make your code more readable and easier to maintain. If there are strings or numbers in your code that don’t change, declare them as constants. Constants are resolved once when your program is compiled, with the appropriate value written into the code. With variables, however, each time the application runs and finds a variable, it needs to get the current value of the variable.
Whenever possible, use the intrinsic constants listed in the Object Browser rather than creating your own. You don’t need to worry about including modules that contain unused constants in your application; when you make an .exe file, unused constants are removed.
Maybe it's really talking about variables but I don't know.
-
Jun 8th, 2004, 06:28 PM
#14
Fanatic Member
I think it means don't do something like:
VB Code:
Dim bla as long
bla = 5
Dim i as long
Dim total as long
for i = 0 to 10
total = total + bla
next
Clearly "bla" is unecessary and that code might cause more fetches from memory. It's a bit of a no-brainer though.
-
Jun 8th, 2004, 07:38 PM
#15
I just found that substituting a constant for a number is faster. Here is the code that I ran as an exe.
VB Code:
Dim lngStart As Long
Dim lngFinish As Long
Dim lngCounterOne As Long
Dim lngCounterTwo As Long
Const FIVE As Integer = 5
' Record the start "time"
lngStart = GetTickCount()
' Some process that you want to time
For lngCounterOne = 1 To 9000000
lngCounterTwo = lngCounterTwo + FIVE
Next lngCounterOne
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
MsgBox CStr(lngFinish - lngStart)
lngStart = GetTickCount()
' Some process that you want to time
For lngCounterOne = 1 To 9000000
lngCounterTwo = lngCounterTwo + 5
Next lngCounterOne
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
MsgBox CStr(lngFinish - lngStart)
On my PC the code using FIVE took 16 ms while the code using 5 took 31 ms.
-
Jun 8th, 2004, 07:47 PM
#16
Fanatic Member
That's pretty strange, it looks like VB does behave like you said. Try more iterations though - GTC's resolution is only ~30ms.
-
Jun 8th, 2004, 08:09 PM
#17
When I change 9000000 to 90000000 I get 187 vs 203.
-
Jun 8th, 2004, 08:56 PM
#18
Fanatic Member
CStopWatch Class by Karl Moore
This is an excellent class you can add to your project and call - great example to show you how to use it....
-
Jun 9th, 2004, 03:48 AM
#19
Fanatic Member
QueryPeformanceCounter is better But that aside, I tested the code on my PC and I'm seeing the opposite - the "5" code runs consistently faster.
Last edited by azteched; Jun 9th, 2004 at 03:57 AM.
an ending
-
Jun 9th, 2004, 03:56 AM
#20
MartinLiss: to get more accurate results, please make two different projects and EXEs. I've seen VB giving weird results when you run two test after each other in one code. As separate I've got much more accurate results.
-
Jun 9th, 2004, 04:11 AM
#21
Fanatic Member
Update: using QueryPerformanceCounter and seprarating out the two tests, I'm seeing no difference in performance between the pieces of code. This is with 900000000 iterations and averaging over 10 runs.
-
Jun 9th, 2004, 04:21 AM
#22
Yup, was as I thought: two tests in the same EXE is unreliable. Maybe this can be skipped in one project by making the tests behind separate command buttons. Thought it'd be plain silly if you had to use declared constants instead of constant numbers.
-
Jun 9th, 2004, 04:28 AM
#23
Fanatic Member
Yeh I put the tests in two functions behind two command buttons. It's not completely ideal, because the test you run first always runs about ~2ms slower, probably because of caching, but the whichever you run first, it's always the case, so the performance is identical.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|