Let others know how useful this tip is by rating it below. Got a tip or code of your own you'd like to share? Submit it here!
This article explains some of the finer points of VB.NET. By gaining an understanding of these issues, you will be able to enhance the performance of your applications.
First, let's have quick look what boxing and unboxing are.
Boxing and unboxing:
In .NET, we have only two major variables types, Value and Reference. There are some cases where we have to convert a Value type to Reference type and vice-versa. Sometimes such conversions are implicit. This is where the concept of boxing and unboxing comes into picture.
Boxing occurs when an instance of a Value type is converted to a Reference type. Unboxing involves the conversion of an instance of a Reference type back to its original Value type.
Normally when a conversion, implicit or explicit, occurs the original value is read from its current memory location and then the new value is assigned. For example, to convert a Short to a Long, the system reads the two bytes of Short data, and writes them the appropriate bytes for the Long variable. However, under VB.NET, if a value type needs to be managed as an object, then the system will perform an intermediate step of boxing. This process does not cause any problems nor does it require any special programming skills, but it has a performance impact.
In a situation in which you are dealing with a single value type this is not a significant cost. However, if you are processing a very big array, the time spent moving between a Value type and Reference type can not be ignored.
Now, let us have a look at explicit conversion, a scenario where we face such performance problem:
In VB.NET, we have various ways to do type conversions, Some of them are taken from previous versions of VB.
The conversion functions such as CBool(), CByte(), CChar(), CInt(), CDbl(), etc. are based on VB6. These functions accept the input as the primitive data type that we want to convert. For example, CDbl() is used to convert Integers, Short, Long, etc. to double.
The disadvantage of these functions is that they have been designed to support any object. This means that if a primitive type is used, the function automatically boxes the parameter prior to getting a new value. This results in performance loss.
To overcome this we can use the Convert class, in which the same functions are used, but in the overloaded fashion, for the different input type. Thus, the conversions are faster when the Convert class is used.
Dim myShortInt = 1
Convert.ToInt32(myShortInt) 'converts a short to int32 type
Passing parameters to functions and procedures:
This is another scenario that needs a mention here. In VB.NET there are two ways in which we can call a function or procedure, viz, by Value or by Reference. The default being Call by Value (Note: In VB6 the default is call by Reference.)
Passing a parameter by Reference means that if changes are made to the value of a variable passed, these changes are reflected back in the calling routine.
Objects are Reference type data. They maintain a reference to where the actual data is stored on the stack. Normally what occurs when an object is passed by reference is that this memory pointer from the stack is passed to the function or procedure. As a result of only passing a pointer to the referenced data, the function or procedure has access to the original data.
However, VB.NET does not follow this model. When an object's property is passed by reference to a function or procedure, the data is copied. Not only is the data copied, but since by definition variables passed by reference allow for the return of changes, the data is copied back. Thus, while most implementation avoid copying the data when a variable is passed by reference, VB.NET actually passes it twice -- a large performance hit on a function call that passes data by reference.
Therefore the ByRef option will use more of the System Resources as the parameter data is copied in for use by the function and then copied back to its original location. On the other hand, ByVal only copies the data once. When considering how to pass parameters this should be kept in mind, and the ability to return data as part of the function as opposed to ByRef alternative should be considered.