Optimizing Code: Avoid Using Variant Variables
Optimizing Code: Avoid Using Variant Variables
Unless you're doing tasks like generating fractals, your applications are unlikely to be limited by
the actual processing speed of your code. Typically other factors — such as video speed,
network delays, or disk activities — are the limiting factor in your applications. For example,
when a form is slow to load, the cause might be the number of controls and graphics on the form
rather than slow code in the Form_Load event. However, you may find points in your program
where the speed of your code is the gating factor, especially for routines that are called
frequently. When that's the case, there are several techniques you can use to increase the real
speed of your applications:
Even if you’re not optimizing your code for speed, it helps to be aware of these techniques and
their underlying principles. If you get in the habit of choosing more efficient algorithms as you
code, the incremental gains can add up to a noticeable overall improvement in speed.
A good way to avoid Variants is to use the Option Explicit statement, which forces you to
declare all your variables. To use Option Explicit, check the Require Variable Declaration check
box on the Editor tab of the Options dialog box, available from the Tools menu.
Be careful when declaring multiple variables: If you don’t use the As type clause, they will
actually be declared as Variants. For example, in the following declaration, X and Y are variants:
Dim X, Y, Z As Long
For More Information To learn more about Visual Basic data types, see "Data Types" in
"Programming Fundamentals."
When performing division, use the integer division operator (\) if you don’t need a decimal
result. Integer math is always faster than floating-point math because it doesn’t require the
offloading of the operation to a math coprocessor. If you do need to do math with decimal
values, the Double data type is faster than the Currency data type.
The following table ranks the numeric data types by calculation speed.
Never get the value of any given property more than once in a procedure unless you know the
value has changed. Instead, assign the value of the property to a variable and use the variable in
all subsequent code. For example, code like this is very slow:
For i = 0 To 10
picIcon(i).Left = picPallete.Left
Next I
picLeft = picPallete.Left
For i = 0 To 10
picIcon(i).Left = picLeft
Next I
Do Until EOF(F)
Line Input #F, nextLine
Text1.Text = Text1.Text + nextLine
Loop
Do Until EOF(F)
Line Input #F, nextLine
bufferVar = bufferVar & nextLine & vbCrLf
Loop
Text1.Text = bufferVar
However, this code does the equivalent job and is even faster:
As you can see, there are several methods for accomplishing the same task; the best algorithm is
also the best optimization.
This same technique can be applied to return values from functions. Caching function return
values avoids frequent calls to the run-time dynamic-link library (DLL), Msvbvm60.dll.
Likewise, calling a procedure that resides in the same module is faster than calling the same
module in a separate .BAS module; if the same procedure needs to be called from multiple
modules this gain will be negated.
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.
Your function uses less stack space per call, and less data is moved in memory, if you use typed
optional arguments:
The typed optional arguments are faster to access than Variants, and as a bonus, you'll get a
compile-time error message if you supply information of the wrong data type.
• Avoid using Before and After arguments when adding objects to a collection.
• Use keyed collections rather than arrays for groups of objects of the same type.
Collections allow you to iterate through them using an integer For...Next loop. However, the For
Each...Next construct is more readable and in many cases faster. The For Each...Next iteration is
implemented by the creator of the collection, so the actual speed will vary from one collection
object to the next. However, For Each...Next will rarely be slower than For...Next because the
simplest implementation is a linear For...Next style iteration. In some cases the implementor may
use a more sophisticated implementation than linear iteration, so For Each...Next can be much
faster.
It is quicker to add objects to a collection if you don't use the Before and After arguments. Those
arguments require Visual Basic to find another object in the collection before it can add the new
object.
When you have a group of objects of the same type, you can usually choose to manage them in a
collection or an array (if they are of differing types, a collection is your only choice). From a
speed standpoint, which approach you should choose depends on how you plan to access the
objects. If you can associate a unique key with each object, then a collection is the fastest choice.
Using a key to retrieve an object from a collection is faster than traversing an array sequentially.
However, if you do not have keys and therefore will always have to traverse the objects, an array
is the better choice. Arrays are faster to traverse sequentially than collections.
For small numbers of objects, arrays use less memory and can often be searched more quickly.
The actual number where collections become more efficient than arrays is around 100 objects;
however, this can vary depending on processor speed and available memory.
For More Information See "Using Collections as an Alternative to Arrays" in "More About
Programming."