|
-
May 29th, 2009, 06:53 AM
#1
Thread Starter
Lively Member
Tips for writing the cleanest, most efficient code? (Also a few related questions)
Hi there. I'm rather new to the VB environment so don't know all the little tips and tricks that experienced programmers pick up, but I still want to make the most efficient code I possibly can. I already have general programming knowledge, but wish to gain VB-specific knowledge in addition.
If any of you have any advice for simple things I can do to increase performance, I would be very grateful if you'd share!
I'm looking for advice somewhat like "Unless absolutely required, don't declare things as Variant," and "Use option explicit", and "When evaluating a value of a control many times in a row, set a variable to that value instead of forcing VB to resolve the path every time it's referenced", just little things that help it compile and run cleaner.
A few specific questions:
I've heard that the Long type is the "native data type" in VB6, and that you can create minor overhead using Integers because of the time spent converting Integers to Longs, is this true?
When referencing methods in other modules, is it better practice to give the full path, or does the whole project compile together so that it doesn't matter? (IE "call someMethod" versus "call someModule.someMethod"
Should I list function and method prototypes at the top, similar to a C header file?
Which loop types compile better and more efficient in VB, and under what circumstances?
Which built-in library functions should I avoid, (if any) and why? Are there any cases where the provided function or method isn't good quality, and I would be better writing my own?
Anyway, VB is a very different environment than what I am used to. It is much more "helpful" and does much more behind the scenes than what I have experienced before, and I don't quite know what the side effects of this are.
Thanks in advance!
-
May 29th, 2009, 08:04 AM
#2
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
Avoid concatenation when you can.
Code:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
Dim lngStart As Long
Dim lngFinish As Long
Dim strTemp As String
Dim ub As Long
ub = 100000
lngStart = GetTickCount
strTemp = Concatenation(ub)
lngFinish = GetTickCount
MsgBox "With " & ub & " cycles using concatenation it " & _
"took " & (lngFinish - lngStart) / 1000 & " seconds to " & _
"generate the results."
lngStart = GetTickCount
strTemp = Joining(ub)
lngFinish = GetTickCount
MsgBox "With " & ub & " cycles and joining an array it " & _
"took " & (lngFinish - lngStart) / 1000 & " seconds to " & _
"generate the results."
End Sub
Private Function Concatenation(ByVal ub As Long) As String
Dim i As Long
Dim strOutput As String
For i = 0 To ub
strOutput = strOutput & Chr((i Mod 26) + 65)
DoEvents
Next i
Concatenation = strOutput
End Function
Private Function Joining(ByVal ub As Long) As String
Dim i As Long
Dim strOutput() As String
ReDim strOutput(ub)
For i = 0 To ub
strOutput(i) = Chr((i Mod 26) + 65)
DoEvents
Next i
Joining = Join(strOutput, "")
End Function
-
May 29th, 2009, 08:06 AM
#3
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
"Unless absolutely required, don't declare things as Variant," and "Use option explicit"
That's all good stuff there.
"When evaluating a value of a control many times in a row, set a variable to that value instead of forcing VB to resolve the path every time it's referenced"
That actually doesn't do anything other than make it easier on the developer.
>>I've heard that the Long type is the "native data type" in VB6, and that you can create minor overhead using Integers because of the time spent converting Integers to Longs, is this true?
Not sure where that came from. Integer is a native type too... the difference is that Integers is a 16 bit type, while a Long is a 32 bit type... which means integers top out at 32646.... anything larger than that results in an overflow error. As a result, most people just simply use the 32-bit Long so we cna have larger numbers.
>>When referencing methods in other modules, is it better practice to give the full path, or does the whole project compile together so that it doesn't matter? (IE "call someMethod" versus "call someModule.someMethod"
Depends.... if you are dealing with a class, then you HAVE to use the class instance.... if it's in a module, then it's not necessary.
>>Should I list function and method prototypes at the top, similar to a C header file?
That's a matter of personal style or shop standards. Personally, it's useless as far as I am concerned... if you make a change to the sub itself, then you have to remember to make changes to the listing back at the top. It just adds additional work that doesn't really need to be there.
>>Which loop types compile better and more efficient in VB, and under what circumstances?
That's more of a case by case situation....and something that simply comes from experience and asking questions.
>>Which built-in library functions should I avoid, (if any) and why? Are there any cases where the provided function or method isn't good quality, and I would be better writing my own?
Again... that's something that will come in time and will depend on the circumstances. Example, the Round function works jsut fine... except we found a case where it didn't quite work the way we needed it to...so we wrote our own. It's not that it was inefficient or had a bug, it was a querk of the system.
>>Anyway, VB is a very different environment than what I am used to. It is much more "helpful" and does much more behind the scenes than what I have experienced before, and I don't quite know what the side effects of this are.
That's by design.... VB is what's known as a RAD environment (Rapid Application Development) ... the idea is to be able to design and develop applications in a rapid manner, allowing for quick prototyping and modifications.
-tg
-
May 29th, 2009, 08:24 AM
#4
Thread Starter
Lively Member
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
 Originally Posted by techgnome
Not sure where that came from. Integer is a native type too... the difference is that Integers is a 16 bit type, while a Long is a 32 bit type... which means integers top out at 32646.... anything larger than that results in an overflow error. As a result, most people just simply use the 32-bit Long so we cna have larger numbers.
Yeah, I'm not sure where I got this or why they said it. When I read it, my impression was that both Longs and Integers were internally stored in the same number of bits, and that for some reason you had to "convert" (Into what? I don't know) the Integer version back and forth to use it. I was really tired at the time, it actually doesn't make any sense at all now that I'm awake. :P
Maybe they were commenting on the difference in VB.NET and VB6 datatype sizes? Bah, who knows.
-
May 29th, 2009, 09:09 AM
#5
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
I agree with techgnome's comments below but have added some other things to think about.
 Originally Posted by techgnome
>>When referencing methods in other modules, is it better practice to give the full path, or does the whole project compile together so that it doesn't matter? (IE "call someMethod" versus "call someModule.someMethod"
Depends.... if you are dealing with a class, then you HAVE to use the class instance.... if it's in a module, then it's not necessary.
Agreed. However, I find it useful to include the module name only because I can readily identify it as a non-local function (i.e., not a function in the current class/form and not an API call).
 Originally Posted by techgnome
>>Which loop types compile better and more efficient in VB, and under what circumstances?
That's more of a case by case situation....and something that simply comes from experience and asking questions.
Agreed. However, use For:Next loops vs Do:While or Do:Until loops when practical.
 Originally Posted by techgnome
>>Which built-in library functions should I avoid, (if any) and why? Are there any cases where the provided function or method isn't good quality, and I would be better writing my own?
Again... that's something that will come in time and will depend on the circumstances...
Should you be writing code that can be shared with VB5 users or used in VB5 projects, be aware that some functions exist in VB6 that do not in VB5.
Last edited by LaVolpe; May 29th, 2009 at 09:33 AM.
-
May 29th, 2009, 09:17 AM
#6
Thread Starter
Lively Member
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
Thank you for the replies so far, they've been exactly what I've been looking for.
The concatenation thing is odd! I suppose it is only significant when there is a large number of things to concatenate? (Instead of just three of four?)
-
May 29th, 2009, 10:38 AM
#7
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
re concatenation - true... in minor cases, it's a trivial thing.... if speed isn't a factor, it's a trivial thing. If speed is a consideration or you are concatenating a large amount of items.... then it becomes an issue. It has to do with the fact that strings are immutable objects. Meaning, once created, they cannot change. ( ) ... so in order to concatenate one string to another, a new memory area large enough for the new string has to be allocated, then the original string copied to it, then the appendment is then copied to the new location, and the whole thing returned. so if you do this A & B .... A gets copied to the new location, followed by B.... If you do A & B & C..... A gets copied to the new location.... followed by B.... then THAT result then gets copied to yet ANOTHER new location, and then followed by C. ... you can quickly see how messy and slow multiple concatenation get. Using JOIN on an array (in VB 6 - or StringBuilder in .NET) by passes alot of that by using optimized routines to get the job done.
-tg
-
May 29th, 2009, 11:34 AM
#8
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
There is a good article on VB6 string optimization over at Aivosto.com
Data types are important to maintain for both performance and memory reasons. This includes the inbuilt functions, ie. Mid is not the same as Mid$.
Long being 32-bit are natively faster with 32-bit processors which most people still use. This means that on every generic purpose Long is your choice for a numeric variable. You use other types only if you see the need.
However, VB automatically coerces data types to other types when it sees the need. When you do something as simple as 1 / 2 you end up with a Double, which is then again coerced back to Long. You can "sort of" get bitshifting with 1 \ 2 and thus end up maintaining the data type all the time.
Using some operators can sometimes be confusing, because they let you combine two incompatible data types. For example, you may do something weird such as "1" + 1. Now, somebody might think the result would be "2", but instead VB ends up doing a string concatenation. Another reason why keeping up to track of the data type you use is important! (This is also why Variant may silently be very evil for people who are new to classic VB.)
VB's own native string functions are very fast when used properly. For example, using Mid$ to move data around can beat Windows API CopyMemory (RtlMoveMemory) any time of the day (may involve some hacking around though). Some specialized functions are also very fast, such as StrReverse, InStr & InStrB (latter much faster, but harder to use; text searching can be done faster with a custom Boyer & Moore algorithm), Left$, Right$...
One especially slow one is IIf, simply avoid it! You can even write your custom IIf function and it'll be tons faster, even if you used Variant data type. DoEvents is another call that should be avoided: it does let your application refresh itself, but it also does tons of extra calls that are often unnecessary to just seemingly keep application alive. It can be used, but it needs some careful consideration.
On Error Resume Next can be quite evil, I'd suggest never to use it for more than against one line at a time.
Split can be beaten by pure VB6 code (you can find my QuickSplit if interested).
Returning arrays from functions and properties is slow, you can instead pass an array variable as a parameter to get things done faster.
If I recall correctly, ByVal for parameters is faster than the default ByRef, except for Strings and Objects. You should pass all numeric data types ByVal unless you wish to modify them in the procedure. You can pass strings ByVal if you want an extra variable and you don't need the original string that was passed except for some initial stuff.
VB6 lacks pointers. This means to get access to other variables avoiding copying memory requires hacking around, but it can be done. It may not always be pretty though. Key things to learn are Safe Array datatype (arrays of VB6 are internally in this format), StrPtr, VarPtr and a few API calls. Most often with VB6 the fastest & most efficient code is very long, while the shortest does the job slowly. There are exceptions. Finding the middle ground is a challenge in itself: making short yet efficient code that is easy to read requires experience.
The biggest issue with people who have a C/C++ background or similar is that when they get VB6, they suddenly kind of forget everything they knew when learning C/C++ and then blame VB6 for bad performance. VB6 doesn't in itself encourage to code in the same fashion, but basically in every case you can blame the programmer if you get slow code. You simply have to know what really happens when you write stuff, and if you don't know for sure, you aren't visiting a forum without a reason
Last edited by Merri; May 29th, 2009 at 11:44 AM.
-
May 29th, 2009, 12:08 PM
#9
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
 Originally Posted by Merri
If I recall correctly, ByVal for parameters is faster than the default ByRef, except for Strings and Objects...
Would disagree with part of that statement. ByRef for Strings is much faster otherwise VB has to copy the string to additional memory (more work). Objects can never be passed ByVal and if tried, you'd really get "ByRef" anyway. This is because objects are passed by pointers. Maybe worse case is passing an object ByVal, VB acutally copies the pointer value to memory for the pass.
Regarding ByVal vs ByRef generally. ByRef should always be faster. ByVal requires making another "copy" of the value, whether allocating memory of shifting stacks.
-
May 29th, 2009, 12:15 PM
#10
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
LaVolpe.... did you read that before commenting? You said you disagreed with it, then confirmed what he said "byVal is faster... EXCEPT FOR Strings and Objects" Meaning for Objects and Strings, byRef is faster. 
-tg
-yes, I'm being pedantic....
-
May 29th, 2009, 12:23 PM
#11
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
 Originally Posted by techgnome
LaVolpe.... did you read that before commenting? You said you disagreed with it, then confirmed what he said "byVal is faster... EXCEPT FOR Strings and Objects" Meaning for Objects and Strings, byRef is faster.
-tg
-yes, I'm being pedantic....
Ugh ignore what I said, I strike it all out.
I actually did disagree, but I was being stupid. ByRef means that a pointer is being passed for the variable. Therefore, to get the value from the pointer, you have to dereference it. Thereby, one would think the cpu cycles would be greater.
Apologize to Merri for the confused thought process on my part.
Last edited by LaVolpe; May 29th, 2009 at 12:48 PM.
-
May 29th, 2009, 12:34 PM
#12
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
Afaik the speed issue with ByRef is that the variable is non-local, which makes it slower to access within the procedure, whereas variable passed ByVal is local to the procedure. Thus despite the extra copy the more you need the variable the faster it gets when it is ByVal.
I just happened to test this some time, but since it is already years ago I've forgotten how I tested it and how I came up with the conclusions. You're welcome to test it again if you really care about it It is quite minor stuff in the end, only useful info if you're making a highly optimized procedure that may be called a lot of times.
One extra detail regarding ByVal and ByRef: ByVal allows to pass different data type than requested. For example, passing a Variant containing a String will give you an error if using ByRef String.
-
May 29th, 2009, 12:51 PM
#13
Thread Starter
Lively Member
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
 Originally Posted by Merri
Returning arrays from functions and properties is slow, you can instead pass an array variable as a parameter to get things done faster.
Hummm, I thought VB wouldn't let you pass arrays by value? I seem to remember trying that when I thought VB default was pass by value (heh) and it threw a compile error... although I probably just had the syntax wrong.
I think the following passes by reference(?):
Code:
dim metersx() as Double
Public Function getMetersx() As Variant
getMetersx = metersx
End Function
Yet another mystery; when I tried declaring the above as
Code:
Public Function getMetersx() As Double
it wouldn't work. Is there something special about returning arrays or array references? (Almost said "Pointer", heh. My C is showing. )
-
May 29th, 2009, 12:57 PM
#14
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
the getMetersx returns A Double (just one).... not an array of doubles....
Code:
Public Function getMetersx() As Double()
NOW, it'll return array of Double
-tg
-
May 29th, 2009, 12:58 PM
#15
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
I bought a book a couple yrs ago called "Practical Standard fo Microsoft Visual Basic by James D. Foxall" One of the best vb books i have. It has a lot of examples like it shows the wrong way, then the right way and tons of tips.
Another consideration is variable naming, using a naming scheme can make all the difference in the world as far as writing fast and efficient code. Here is an example:"hungarian naming convention"
http://msdn.microsoft.com/en-us/library/aa260976.aspx
Waiting for a full featured smart phone with out marrying a provider
Go Android
Go raiders 
-
May 29th, 2009, 01:10 PM
#16
Thread Starter
Lively Member
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
 Originally Posted by techgnome
the getMetersx returns A Double (just one).... not an array of doubles....
Code:
Public Function getMetersx() As Double()
NOW, it'll return array of Double
-tg
Does it act differently in VBA, do you know? Because the code I've used (pretty much exactly as posted) behaves as if it were passing a reference to a single array instead of by value or only returning the first element... I definitely get an array out of it. 
edit: oooh, unless you were saying it returns a single double when declared "As Double", but returns an array when declared "As Varient"... Yeah, that appears to be what it does. I'm so unfamiliar with this weird "Varient" thing, haha.
Last edited by nanoinfinity; May 29th, 2009 at 01:15 PM.
-
May 29th, 2009, 01:14 PM
#17
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
As Double
returns a single Double variable.
As Double()
returns an array of Double. Was a new thing in VB6.
As Variant
returns a Variant that might contain an array of Double or maybe just a Double. Was the only way to return an array before VB6.
-
May 29th, 2009, 02:47 PM
#18
Hyperactive Member
Re: Tips for writing the cleanest, most efficient code? (Also a few related questions
See the link in my sig "Improved DoEvents" for the standard code that pretty much everyone uses instead of "DoEvents".
Last edited by deathfxu; May 29th, 2009 at 02:47 PM.
Reason: typo
Tags for this Thread
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
|