Visual Basic Concepts
When reducing the size of an application is important, there are a number of techniques that you can apply to make your code more compact. In addition to reducing the application’s size in memory, most of these optimizations will also reduce the size of the .exe file. As an additional benefit, a smaller application will load faster.
Most size optimization techniques involve eliminating unnecessary elements from your code. Visual Basic automatically eliminates certain elements when you compile your application. There is no reason to restrict the length or number of the following elements:
None of these elements affect the size of your application in memory when it is running as an .exe file.
Other elements, such as variables, forms, and procedures, do take up space in memory. It is usually best to streamline these. There are several techniques you can use to reduce the memory your application occupies when it is running as an .exe file. These techniques can reduce code size:
Each loaded form, whether visible or not, consumes a significant amount of memory (which varies with the number and types of controls on the form, the size of bitmaps on the form, and so on). Load forms only when you need to display them, and unload them (rather than hide them) when you no longer need them. Remember that any reference to properties, methods, or controls on a form, or a form variable declared with New, causes Visual Basic to load the form.
When you unload a form using the Unload method, only a portion of the memory occupied by the form is released. To free all memory, invalidate the reference to the form by using the Nothing keyword:
Set Form = Nothing
When designing your application, try to place as few controls on a form as possible. The actual limit depends on the type of controls as well as available system, but in practice, any form with a large number of controls will perform slowly. A related technique is to use control arrays where possible, rather than putting a large number of controls of the same type on a form at design time.
For More Information To learn more about control arrays, see "Working with Control Arrays" in "Using Visual Basic’s Standard Controls."
Label controls use fewer Windows resources than text boxes do, so you should use labels in place of text boxes whenever possible. For example, if you need a hidden control on a form for storing text, it is more efficient to use a label.
Even a data entry form that requires numerous text fields can be optimized using this technique. You can create a label for each field and use a single text box for input, moving it to the next label's location in the LostFocus event:
Private Sub Label1_LostFocus()
' Update Label1
Label1.Caption = Text1.Text
' Move the Textbox over the next label
Text1.Move Label2.Left, Label2.Top
' Update Text1 contents
Text1.Text = Label2.Caption
End Sub
You can make a label look like a text box by setting the BackColor and BorderStyle properties. Although this technique requires more code, it can significantly reduce resource usage for a form that contains numerous fields.
Data you place directly into your application at design time (as properties or as literal strings and numbers in your code) increases the memory the application consumes at run time. You can reduce memory by loading the data from disk file or resources at run time. This is particularly valuable for large bitmaps and strings.
For More Information For information on adding resources to your application, see "Resource Files" in "Advanced Programming Features."
Visual Basic loads modules on demand — that is, it loads a module into memory only when your code calls one of the procedures in that module. If you never call a procedure in a particular module, Visual Basic never loads that module. Placing related procedures in the same module causes Visual Basic to load modules only as needed.
The Variant data type is extremely flexible, but it is also larger than any of the other data types. When you must squeeze every last byte out of your application, consider replacing Variant variables, and especially arrays of Variant variables, with other data types.
Each Variant takes 16 bytes, compared to 2 for an Integer or 8 for a Double. Variable-length String variables use 4 bytes plus 1 byte per character in the string, but each Variant containing a string takes 16 bytes plus 1 byte per character in the string. Because they are so large, Variant variables are particularly troublesome when used as local variables or arguments to procedures, because they quickly consume stack space.
In some cases, however, using other data types forces you to add more code to compensate for the loss of flexibility that the Variant data type provides, resulting in no net reduction in size.
Consider using dynamic arrays instead of fixed arrays. When you no longer need the data in a dynamic array, use Erase or ReDim Preserve to discard unneeded data, and reclaim the memory used by the array. For example, you can reclaim the space used by a dynamic array with the following code:
Erase MyArray
Whereas Erase completely eliminates the array, ReDim Preserve makes the array smaller without losing its contents:
ReDim Preserve MyArray(10, smallernum)
Erasing a fixed-size array will not reclaim the memory for the array — it simply clears out the values of each element of the array. If each element was a string, or a Variant containing a string or array, then erasing the array would reclaim the memory from those strings or Variants, not the memory for the array itself.
The space used by (nonstatic) local string and array variables is reclaimed automatically when the procedure ends. However, global and module-level string and array variables remain in existence for as long as your program is running. If you are trying to keep your application as small as possible, you should reclaim the space used by these variables as soon as you can. You reclaim string space by assigning the zero-length string to it:
SomeStringVar = "" ' Reclaim space.
Similarly, you can reclaim some (but not all) of the space used by an object variable by setting it to Nothing. For example, to remove a Recordset object variable:
Private rs As New RecordSet
… ' Code to initialize and use recordset would go here
rs.Close ' Close the recordset
Set rs = Nothing ' Set the object reference to Nothing
If you don’t explicitly set an object reference to Nothing, a reference to the object will remain in memory until the application is terminated; for an application that uses a lot of objects this can quickly consume your available memory and slow the application.
You can also reclaim space by unloading forms and setting them to Nothing rather than simply hiding them when they are no longer needed.
As you develop and modify your applications, you may leave behind dead code — entire procedures that are not called from anywhere in your code. You may also have declared variables that are no longer used. Although Visual Basic does remove unused constants, it does not remove unused variables and dead code when you create an .exe. Consider reviewing your code to find and remove unused procedures and variables. For example, Debug.Print statements, while ignored in the run-time .exe, are sometimes present in the .exe file.
Debug.Print statements with strings or variables as arguments are not compiled when you create an .exe. However, where Debug.Print statements have a function call as an argument, the Debug.Print statement itself is ignored by the compiler, but the function call is compiled. Then, when the application is run, the function is called but the return is ignored. Because functions that appear as arguments to Debug.Print will take up space and cycle time in an .exe, it may be beneficial to delete these statements before you make an .exe.
Use the Find command on the Edit menu to search for references to a particular variable. Or, if you have Option Explicit statements in each of your modules, you can quickly discover if a variable is used in your application by removing or commenting out its declaration and running the application. If the variable is used, Visual Basic will generate an error. If you don’t see an error, the variable was not used.
For More Information To learn more about the Debug.Print statement, see "Printing Information in the Immediate Window" in "Debugging Your Code and Handling Errors."