Writing Efficient VB Software

Tuesday Nov 19th 2002 by Yash Kumar
Share:

Writing Efficient VB Software

I know many of you out there never gave it a thought. Whatis efficient software. An efficient piece of software is software that not only cutsback on system resources, but runs faster than other software performing the samefunction. This tutorial is designed to make you write software that is 10 times fasterthan what you will normally write. This is a must read for any developer. Itcontains dozens of techniques that will greatly help you create efficientsoftware. Before I start the actual tutorial, Ill list some principles that you should followwhen reading this tutorial:

  • Get it Right the first time: One of the most common mistakes made by programmers is that they scribble down whatever code they like and then come back to try and optimize it. Eventually they find out they have to rewrite the procedure again. So get it right the first time

 

  • Dont get carried away:. Eventually, even after you've written an efficient piece software, you will or should come back to revise and correct your code. I would like to make it clear as to not get carried away doing so. Ive seen many programmers do so. So, go through your code. If you find a loop or fragment of code that you feel you could improve by around 1 second, go for it. But if it's something you could only improve by 100 ms, leave it the way it is. Rewriting it will just cause more bugs to creep in and more testing. So, you need to balance the costs in making such changes. Also, the user would normally not feel a difference unless the change is a significant one.

 

  • Use OOP wherever required: For those of you who dont know, OOP stands for Object Oriented Programming. In Visual Basic, it is simply the usage of classes. Most of you might know that usage of objects (classes in this case) can be highly inefficient and should be avoided. I would go against this. Efficient does not only mean making speedy software, it means making manageable and less bug prone software. Using classes will greatly help in all these things. So if you fell that your software really needs a class, please use one. This tutorial should help you speed up the internal working of the class.

When making efficient VB software, always keep theseprinciples in mind. Now lets get on with the actual tutorial, which has beendivided into 2 sections, Speeding up your code and Compiler Optimizations.

Oneof the first things you could do to make efficient software is to speed up your code.Several techniques are mentioned below:

UsingIntegers and Longs:
One of the most obvious ways to speed up your code is choosing the correct data type.This could make a big difference in the speed of your code. In most cases, it is possible to replace the usage of Singles, Doublesand Currency with either Integers or Longs.

One of the most common reasons people will opt for a currency or double value isbecause it can stores decimals. But decimal values could be easily stored inintegers. Ask how? This can be done by assuming suppose, the last 3 numbers ofan integer are decimal values. Then, you could simply display the result bydividing it by 1000. Heres an example.

Dim intNum as Integer
lets say someone enter a number which youknow has 3 numbers after the decimalpoint. You could store it in an integer bymultiplying it by 1000
intNum = txtDecimalNum.text * 1000     Decimal value stored
MsgBox intNum / 1000 Decimal value retrieved

Byusing integers besides doubles and currencies, you could speed your code by upto 10 times. Try it your self.

AvoidingVariants and Objects:
Thisis one of the most obvious things you could avoid to speed up your code. Butincase you dont know, Ive mentioned it. A variant takes 16 BYTES OFSPACE!! which is very inefficient opposed to an integer that takes only 2 bytes.See the difference. Variants are mainly used for beginners who dont know allthe data types. Since a variant automatically converts a value to itsappropriate data type, its considered a blessing for beginners. But, now it'stime you stopped using it. Just converting the value needs a lot of computingpower. What I mentioned is probably obvious but Id like to point out anothermistake people make with both objects and variants:

DimFSO

Set FSO = New Scripting.FileSystemObject

Or

Dim FSO as object
Set FSO = New Scripting.FileSystemObject

Pleasedo not attempt writing such code. First enough memory is located to create avariant (16 whole bytes) then, more time and memory is wasted in assigning it toan object. Why not just define the whole thing in one line like:

Dim FSO as New FileSystemObject

Itsaves time and memory. Try it for yourself!

Avoidaccessing properties:
Oneof the most common, inefficient codes I find is using properties over and overagain (especially in a loop) where a variable can be used. It is 20 times fasteraccessing a variable than a property. Let me make this clear. Heres anexample of what many people will write

Dim intCon as Integer
For intCon = 0 to Ubound(SomVar())
     Text1.Text = Text1.Text & vbcrlf & SomeVar(intCon)
Next intCon

Thisis highly inefficient. I could rewrite this to make it 20 times faster

Dim intCon as IntegerDim sOutput as StringFor intCon = 0 to Ubound(SomeVar())
      sOutput = sOutput & vbCrlf &SomeVar(intCon)
Next
Text1.Text = sOutput

Tryboth these procedures and see the difference

UsingArrays rather than Collections:
Unlessyou absolutely cant manage without a collection, you should ALWAYS use anarray as its 100 times faster. There are many reasons why so. One reason is its an object while array is an array of variables. Using collections willalways be slower. Another reason is that again, youll be accessing a propertyrather than a variable which makes things worse.

Unrollyour loops:
Manya time Ive seen people using a loop for something that can be done in 5 or 6lines of code. Using loops should be avoided but not to such an extent that bugswould creep into your code. So, as to principle 2, dont get carried away

Using inline code:
Oneof the most inefficient things you could do is call a function that does only 2lines of work. In most cases, calling the function will take more processingpower than executing the code. So unless its a really big procedure, youshould just copy and paste that code into your procedure.

Reducing Object Reference.
For those who are new to OOP, every dot carries down to a new object in an objecthierarchy. Suppose you want to access the text property of a text box in anotherform. Youll access it in the following manor:

MyForm.Text1.Text

Hereyou are going through 2 sets of objects which can be highly inefficient.Unfortunately, there is no work around besides making it more efficient forseveral such accesses. What I mean, if you need to access several suchproperties of Text1  (or anysuch sub object) at the same time, you could do 2 things. Either use Withor assign the object to another object. Heres how:

Usingwith
With frmMain.Text1
     .Text = Learn VB
     .Alignment = 0
     .Tag = Its my life
     .BackColor = vbBlack
     .ForeColor = vbWhite
End With

OR

Dim txtTextBox as TextBox
Set txtTextBox = frmMain.Text1
Now you could just access its properties like
TxtTextBox.Text = Learn VB
TxtTextBox.Alignment = 0
TxtTextBox.Tag = Its my life
TxtTextBox.BackColor = vbBlack
TxtTextBox.ForeColor = vbWhite

Boththese techniques should only be used for accessing many properties or methods ofthe same SUB OBJECT. One mistake Ive seen people do is

With Text1
     .Text = Learn VB
     .Alignment = 0
     .Tag = Its my life
     .BackColor = vbBlack
     .ForeColor = vbWhite
End With

DONOT DO THIS.  Look, this is onlyslowing the code. The With branch adds extra processing to be done. Youare only going to be accessing the properties for that object and not any subobject. The only reason I could see someone to do something like this is thathes extremely lazy.

Testing for EmptyStrings:
One of the things Ive been disgusted at is the way people test for emptystrings. Most of you might know this but for those who dont, makingcomparisons needs much more processing power than accessing properties. Hereswhat many of you do
If Text1.Text = "" then
     Do something
End if

Besidesthis, you could use this piece of code which does exactly the same thing but 20times faster:

If Len(Text1.Text) = 0 then
     Do something
End if

Omitthe Next Variable:
Simplyremoving the variable that follows the next statement could speed your code up alittle.

Normallyyou write:

For intCon = 0 to 10
     Do something
Next intCon

Instead,you could use

For intCon = 0 to 10
     Do something
Next

Thismakes a real difference in nested loops

UsingArrays rather than multiple variables:
Itsalways more efficient to use an array rather than multiple variables. If you need to work with a large number of variables storing similardata, consider using an array. An array is one of the most versatile codingcomponent you have in your VB development arsenal

UsingDynamic arrays rather than fixed arrays:
Themain reason you should use dynamic arrays is because it saves on memoryresources although it doesnt really affect processing speed. A dynamic arrays dimensions could be resized using the ReDim statement.

Destroyingyour objects:
Whateversoftware you make, you are responsible for making sure your software is wipedout from the users memory after he decides to close it. Many programmersreally dont care leaving the user to download RAM cleaners or defragmenters.If they were more responsible programmers, these programs would not be sellingin the market the way they are doing now.

Thisinvolves the destroying of all objects and forms. Normally, youll be using alocal object in a procedure which should be destroyed in the end. Heres anexample

Dim FSO as New FileSystemObject
Do something with it
Now destroy it
Set FSO = Nothing

Samething should be done with forms. They can be wiped out as follows:

Unload frmMain
Set frmMain = Nothing

Dynamicvs Fixed length strings:
Technically,a Fixed length string requires less computing power and space. But, thedisadvantage of a Fixed length string is that you almost, all the time, arerequired to use the Trim function. Therefore you are better off using adynamic string

UseClass modules instead of ActiveX Controls:
Unlessyour ActiveX control is a GUI component, always use a light-weight class moduleinstead. Using a class module instead of an ActiveX control saves tons ofprocessing power.

UsingInternal objects:
Whatmany people normally do with their ActiveX controls or DLLs is compile it andthen add it to their project in the compiled form. This should NEVER be done. Ittakes tons of processing power to link Visual Basic with an external object.Every time you make a call or access a property, you are wasting systemresources and time accessing that external object. If youve made that DLL orActiveX component, you are better off keeping it as a private component in yourproject. Try it out your self. You will definitely be able to see the speeddifference

Usinglesser modules:
Manypeople prefer to store commonly used routines in a module. I wouldnt disagreewith that. But the stupidity of having a module containing 20 to 30 lines ofcode is ridiculous.  If you reallydont require a module, dont use it. If you do, use only 1 or 2. Trykeeping all your routines in one module. The reason for this is that VisualBasic loads a module only when a routine is called from it and only closes itwhen the software is finished. By using only 1 module, Visual Basic will have toload only one, thus saving time and system resources

UsingObject Arrays:
Whiledesigning the User interface, you should always use object arrays rather than aseparate name for the objects that do the same thing. Try adding 100 pictureboxes having different names and press the Start button. Now, add 100 pictureboxes that are in an object array and then press the Start button. Youll seea remarkable decrease in loading time

Usingthe Image control rather than the Picture Box:
Thepicture box is a very heavy weight control whose purpose isnt solely for thedisplay of images. A much more efficient control to use instead of it would bethe Image control

Usingthe Move method:
Anotherthing that really slows things up is using all 4 properties of a UI control toresize and move it. A typical idiot would do this:

Image1.Width = 100
Image1.Height = 100
Image1.Top = 0
Image1.Left = 0

Movingand resizing a control like this is highly inefficient. There are 2 reasonsbehind this is that you are accessing 4 properties of the control and, each timeyou make a change to the controls coordinates or size, it will repaint theENTIRE FORM. So, in the above case, you end up repainting the entire form 4times. All this can be reduced by using a simple function

Image1.Move 0, 0, 100, 100

Useless pictures:
Picturescause a huge burden on memory and require more processing power. Its alwaysbetter to use a background color, at least from the technical point of view.

UsingActiveX DLLs rather than ActiveX Controls:
Ifyou plan to make an ActiveX control that doesnt have a User Interface andrather is a set of classes, always use an ActiveX DLL.

Manyof you probably havent even gone through the set of Compiler options that areavailable. Ive done a little research and will attempt to explain whateveroptions the Visual Basic Compiler offers:

P-CodeVS Native Code:
Onething you might have noticed is that you can choose whether to compile yoursoftware as Native Code or P-Code (pseudocode). The default option is Nativecode and should be left like that.

Whatis P-Code?
Whenpressing the Start button in the Visual Basic IDE, the Visual Basic compileseach line into P-Code and interprets it. This is much faster than Native Code inthe IDE circumstance. By choosing to compile your software into P-Code, VisualBasic will store that code into an EXE where it will be interpreted line by linefor the rest of its life

Whatis Native Code?
NativeCode came out with Visual Basic 6.0. Running Native code is much faster thanrunning P-Code in an exe case. When compiling to Native Code, Visual Basiccompiles your software into the instruction set of the processor chip on yoursystem

Onething Ive noticed in Native Code, that unlike P-Code, it might give youstrange bugs. Many of you might not have faced such a problem but I have. Mycode runs perfectly in the IDE as it runs P-Code. But after I compile it, Isometimes (very rarely) get strange errors. Most of them occur while unloadingforms or some of them occur while displaying the Printer Dialog box over a modalform. I resolved these problems by putting the DoEvents statementin-between the code. I repeat, this happens only rarely and with some types ofsoftware.

Sowhat should you use? Leave it to Native Code.

OptimizeFor Fast Code:
Thisoption is only available if you decide to compile your software to Native Code.This tries optimizing the code to make it faster but it might compile larger.This should remain checked.

OptimizeFor Small Code:
Thisisnt recommended. This option is able to shrink the size of the software butby making it slower.

NoOptimization:
Thecompiler will simply convert the P-Code to Native Code without anyoptimizations. Only recommended if you are constantly getting errors in yourcompiled software.

FavorPentium Pro:
Althoughthis isnt the default option for the Native Code compiler, I always check itand would recommend you check it to. Favor Pentium Pro allows you to favor thePentium Pro instruction set over the normal Pentium one. This could cause yoursoftware to run much faster on Pentium Pro and Pentium 2 + machines. Checkingthis does not mean that it will not run on other computers, it will just run alittle slower. A risk Im willing to take knowing many users use Pentiummachines these days and not 486s.

AdvancedOptimizations:
Mostof these settings can really increase the speed of your software, but leave itprone to bugs. Therefore, I dont recommend it. But I wouldnt say no. Ifyou have big loops or complex math involved that takes a long time, some ofthese optimizations could speed up your procedure dramatically. If you decide touse any of the Advanced Optimizations, you should test your software thoroughly.

  1. Assume No Aliasing:  Could greatly speed up your code in loops but could cause problems if a variable is updated through a different name. What I mean is when you pass a variable by reference to a procedure which changes it, it could cause several errors or plain wrong results.
  2. Remove Array Bound checks, Remove Integer Owerflow Checks and Remove Floating Point Error Checks: All these are important checks that take place in your software. Error handlers pick up when such errors occur. But, by removing these checks, errors could go unnoticed. But, if you are sure that they won't affect your softwares final result, you could check them as they will greatly improve performance.
  3. Allow Unrounded Floating Point Operations: Checking this option will allow the compiler to manage floating point operations much more efficiently and faster. The only draw back of checking this would be that initial values are kept at a much higher precision. This could affect comparison, as normally the compiler would round off these values.
  4. Remove Safe Pentium FDIV Checks: Earlier, some Pentium CPU chips, under certain conditions, returned a bad result while manipulating floating point values. By default, the compiler checks for this error and it should not be removed.

Please dontforget to leave a comment. If you have anything to contribute to this article,please write me an email at Yash@apyl.com

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved