Go the PrintPreview OCX web site for VB 4.0, VB 5.0

Visual Basic tips for optimizing your code

The tips were collected by Tuomas Salste, a BASIC programmer since 1985, and a Visual Basic programmer since 1993.

VBShop - The Visual Basic Shop

Shareware tools for Visual Basic programmers. Tips and user survey results


This page includes some tips on

If you need more tips, check some VB Books!


Optimizing for memory

Get rid of dead code

Unused code increases EXE size. It also slows down your program, and makes it difficult to understand.

Project Analyzer helps you to find all dead code.

Type your variables

VB's default data type is Variant. Avoid Variants when possible. They are slow, and they consume memory.

  1. If you use Variant instead of, say, Integer you waste 14 bytes of memory. This can be significant in a large project.
  2. Integers are much faster than Variants. This is true particularly in For..Next loops.

Use Option Explicit to force declaration of your variables. This helps you to get rid of unnecessary Variants.

Project Analyzer helps you to find missing Option Explicits and implicit Variants.

Avoid fixed-length Strings

Fixed-length strings occupy more memory than variable-length ones. The problem is worse if you have to reserve lots of space for long strings in your fixed-length String variables.

Avoid static variables

Static variables are those that reside in the memory for the whole execution time. The opposite of static variables are dynamic variables. Dynamic variables are procedure-level variables that are created when the procedure is entered, and destroyed when the procedure ends.

Use the following table to determine whether your variables and arrays are static or dynamic.

Variables Arrays
Static
  1. Variables you declare in the (declarations) section
  2. Variables you declare inside a procedure with the Static keyword
  1. Arrays you declare with subscripts in the (declarations) section, like this:
    Dim MyArray(45, 65) As Integer
  2. Arrays you declare inside a procedure with the Static keyword
Dynamic
  1. Variables you declare inside a procedure
  1. Arrays you declare without subscripts in the (declarations) section, like this:
    Dim MyArray() As Integer
  2. Arrays you declare inside a procedure with the Dim or ReDim keyword

Reclaim memory after use

If you are using static variables, it's important to reclaim the memory they occupied when you don't need the variables any more. With dynamic variables memory isn't so much of a problem, because they are destroyed when the procedure ends.

The below table shows how you can reclaim the memory occupied by different variable types. Arrays are discussed below the table.

Type of variable Code to reclaim occupied space
Variable-length String MyString = ""
Variant MyVariant = Empty
Form Unload MyForm
Object Set MyObjectVariable = Nothing

Arrays

Arrays are often memory-hungry. This applies especially to static arrays, whose size is fixed for the lifetime of the program. Dynamic arrays are better for memory optimizations, because they can be resized. However, some memory optimization can be applied to both array types.

One way to reclaim space occupied by an array is to clear all its elements one by one as shown above. Another way is to use Erase or ReDim.

Some graphics optimizations

  1. Reclaim graphics memory with LoadPicture() and Cls.
    You can also set the Picture property to Nothing (VB 4.0 and later).
  2. Use Image controls instead of PictureBoxes.
  3. Use RLE, GIF, JPG, and WMF picture formats instead of BMPs. If possible, try to reduce the number of colours in your pictures.
  4. Load a picture only once. If you need to display one picture in several places, you can just assign it from one control to another, like this:
    MyGraph.Picture = OldGraph.Picture
  5. Set AutoRedraw = False. If it's True, VB will create an AutoRedraw image that consumes memory.

Optimizing for speed

Some memory optimizations described in the previous chapter contribute to speed optimization too. These are getting rid of dead code and using appropriate variable types instead of Variants. On many occasions, when you minimize memory usage you will also minimize execution time. In some cases, however, the two goals may be contradictory.

Now some ways to make faster code.

Cache properties in variables

If you are going to need the value of a property more than once, assign it to a variable. Variables are generally 10 to 20 times faster than properties of the same type.

Use For Each..Next instead of For(index)..Next

Collections allow you to iterate through them using an integer For(index)..Next loop. However, For Each..Next is often faster. Besides, it's easier to read too!

Check for loops

Normally, loops are those parts of a program that take the most time to execute. The worst thing is several loops nested.

Mathematical complexity

You may have heard of mathematical complexity measures like O(n) and O(n2). O(n) means that the execution time of a procedure is proportional to the input size n. O(n2) means it's proportional to the square of the input size. In other words, O(n) is much faster than O(n2), if n is large.

The worst case is denoted by O(2n). This means that execution time rises exponentially when n increases. On the other hand, if execution time rises only logarithmically, like O(log n), you have a fast procedure even for large sets of data.

Very briefly, you calculate mathematical complexity like this:

Code example Complexity

Sub FastProcedure(n)

For i = 1 to n
   Debug.Print "Hello, world!"
Next

End Sub
O(n)

Sub SlowProcedure(n) 

For i = 1 to n
   For j = 1 to n
      Debug.Print "Hello, world!"
   Next
Next

End Sub
O(n2)

Sub SlowestProcedure(n) 

For i = 1 to n
   SlowProcedure n
Next

End Sub
O(n3)

Mathematical complexity (and the time to execute) is mostly due to the number of nested loops. With a recursive procedure (procedure that calls itself), the problem isn't that simple, but most of VB procedures are not recursive.

Project Analyzer detects nested loops, which is a very rough estimate of mathematical complexity.

Working with objects

Minimize the dots. Each dot consumes some time, and makes the code more difficult to read. You can refer to an object's default property just with the name of the object (without the name of the property!). You can also assign an object to an object variable, like this:

Dim X As SomeObject
Set X = SomeContainer.SomeObject(123)

Now you can refer to X instead of the long expression SomeContainer.SomeObject(123). In VB 4.0 and later you can use With..End With for the same effect.

Use early binding. If you know what the type of an object will be, declare your variables with that type. Avoid variables of the general type Object as long as you can. Use the specific type instead.

Optimize display speed

Often it's important how fast your application appears to run, even if the the actual speed isn't that high. Some ways to speed up display speed:

  1. Set ClipControls property to False.
  2. Use Image instead of PictureBox, and Label instead of TextBox, if possible.
  3. Hide controls when setting properties. This prohibits multiple repaints.
  4. Keep a form hidded but loaded if you need to display it fast. The drawback of this method is that it consumes some memory.
  5. Use background processing for longer runs. You can achieve background processing with appropriately placed DoEvents. A good place to put DoEvents is inside time-consuming loops. This needs some consideration, because the user might click some buttons, for example, and your program must know what the user is allowed to do when the background process is running. Set flags like Processing=True and check them in appropriate places.
  6. Use progress indicators.
  7. Pre-load data you will need later. For example, you can load the contents of a database table into an array for faster access.
  8. Use Show in Form_Load event.
  9. Simplify your startup form, or use a splash screen.

How to make understandable code?

A few guidelines:

Project Analyzer generates extensive project documentation with your comments included. It also measures the length of names.

Split complex procedures

Overly long and complex procedures are hard to understand. They are error-prone. One particular sign of a complex procedure is the amount of nested conditionals (if, do..loop, select case).

Project Analyzer detects complex procedures in a number of ways.

Use ByVal parameters

By default, all parameters to a VB procedure are passed by reference. Consider, for example, the following piece of code:

Function MultiplyByTwo(x As Integer) As Integer

x = x * 2
MultiplyByTwo = x

End Function

...

MyNumber = 7
Debug.Print MultiplyByTwo(MyNumber)

How much is MyNumber after a call to MultiplyByTwo? It's 14, although one would easily think it's still 7!

This is because MultiplyByTwo doubles the value of parameter x before returning it back, and the change reflects in MyNumber. In fact, passing parameters by reference means that MyNumber and x are the same variable!

The solution to this is easy. Pass the parameter by value using ByVal, like this:

Function MultiplyByTwo(ByVal x As Integer) As Integer

Now, even if MultiplyByTwo changes the value of x, it will never change the value of MyNumber in the calling procedure.

If you really want to use by reference passing, use it explicitly like this:

Function MultiplyByTwo(ByRef x As Integer) As Integer

Use Private

Whenever possible, use the keyword Private. This will make your procedures and variables accessible inside the module only. The advantage is increased modularity in your code.

Private MyVariable As Integer
Private Sub MyProcedure()

Project Analyzer detects variables, constants and procedures that could be declared Private.


How to make robust code?

Use error handlers

VB crashes easily. This is especially nasty with database programming - Access databases often get corrupted. A fast way to prevent crashing is to use On Error Resume Next.

A still better way is to implement real error handlers. You could try VB/Rig to automatically insert error handlers in your code. It's shareware by Brad Kaenel.

Test with database locking

A common reason for database applications to behave strangely is locking. In a multiuser environment, a database table cannot always be opened, because another user is using it.

To tackle this problem, design error handlers carefully. To test them, you may use DB Lock.


How to develop more efficiently?

Reuse, reuse, reuse!

Reusability is the magic word of programming today. In VB, you can reuse procedures, code modules, or class modules. Reuse greatly reduces the time to develop a program.

You can achieve reusability if you program in an object oriented language creating reusable classes. Although VB isn't a strictly object oriented language, it has a simple class mechanism called class modules (.cls). Visual Basic 5.0 also creates ActiveX objects, that are quite a powerful mechanism for reuse.

Project Analyzer measures reusability in 2 ways:

  1. It shows the number of procedures that call a procedure. The larger the number, the more reusable your probably procedure is.
  2. An extension to Project Analyzer, called Super Project Analyzer, even calculates cross-project reuse ratios.

Some interesting survey results

Problems experienced by VB users.

Other programming languages used by VB programmers.

GeoCitiesRank My SiteTake A TourMy GuestbookChat
Pages Like MineSearchSend This PageForums
Email Me
ResearchTriangle