VB.NET Performance Related Compiler Options
VB.NET offers two compiler options that could potentially improve the overall performance of your application. One of them, Remove Integer Overflow Checks
, is pretty straight forward about what it does and can easily be evaluated by looking at the resulting IL. Here’s an example:
1
2
Dim i As Integer = 1
i = i \ 5
The resulting IL (with overflow checking enabled):
L_0000: ldc.i4.1 // Pushes the integer value of 1 onto the evaluation stack as an int32.
L_0001: stloc.0 // Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
L_0002: ldloc.0 // Loads the local variable at index 0 onto the evaluation stack.
L_0003: ldc.i4.5 // Pushes the integer value of 5 onto the evaluation stack as an int32.
L_0004: mul.ovf // Multiplies two integer values, performs an overflow check, and pushes the result onto the evaluation stack.
L_0005: stloc.0 // Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
L_0006: ret // Returns from the current method, pushing a return value (if present) from the caller's evaluation stack onto the callee's evaluation stack.
And now with overflow checking disabled:
L_0000: ldc.i4.1 // Pushes the integer value of 1 onto the evaluation stack as an int32.
L_0001: stloc.0 // Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
L_0002: ldloc.0 // Loads the local variable at index 0 onto the evaluation stack.
L_0003: ldc.i4.5 // Pushes the integer value of 5 onto the evaluation stack as an int32.
L_0004: mul // Multiplies two values and pushes the result on the evaluation stack.
L_0005: stloc.0 // Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
L_0006: ret // Returns from the current method, pushing a return value (if present) from the caller's evaluation stack onto the callee's evaluation stack.
The code is nearly identical except for line 4. With overflow checking enabled, the mul.ovf
opcode will be used, however, when disabled, the mul opcode is used. The mul.ovf
will do an overflow check on the variable, meaning validate that the result is within the valid range. If not, it will throw an exception. Considering how many calculations you probably do throughout your application, you can imagine how many of these checks will occur throughout it’s lifetime. Keep in mind, I’m just showing multiplication and the overflow checking occurs on nearly every calculation and you can see how that could add up. VB.NET has this overflow checking on by default. If you are aware of the potential issues and write your code to check for overflows where appropriate, then disabling overflow checking can improved the overall performance of your application pretty easily. Note: C# has overflow checking off by default.
Now on to the second compiler option, the Enable Optimizations, which is on by default for the Release configuration. What exactly this option means is kind of a mystery to me. Sure, the following from the documentation sums it up nicely, however, what exactly can one expect to gain by enabling optimizations? Here’s a snippet from the online docs:
Compiler optimizations make your output file smaller, faster, and more efficient. However, because optimizations result in code rearrangement in the output file, /optimize+ can make debugging difficult.
All modules used by an assembly must have been built using the same /optimize settings as the assembly’s /optimize setting.
So, let’s break up the first sentence a bit. “output file smaller” seams self-explanatory, so we’ll move on. “faster”, hmmmm… what does that actually mean? How does it make it faster? What is made faster? And for the last item in the first sentence, “more efficient”. Kind of makes me want to ask the same questions all over again. Also, since not a lot of explanation goes into this, what potential problems might I face by having it turned on as opposed to turned off? It does state that turning it on can “make debugging difficult”. OK, makes sense, however, we are talking about a release build in this context, so debugging shouldn’t be an issue. Why is it even an option then? Basically, I just want to know what kind of results one can expect by having it turned on as opposed to off. What kind of applications would you see a difference?
And finally, Enable Optimizations is on by default, however, Remove Integer Overflow Checks is off by default. I can understand why this might be… but how do I turn it on by default for all my new applications. I understand the issue and always try to do proper checking on my own while developing. I don’t think I need to rely on the compiler option to check for integer overflows… so how can I turn this option on by default.
It would make sense to modify the Program Files\[VS.NET Folder]\Vb7\VbProjects\EmptyProject.vbproj
file by adding the line:
RemoveIntegerChecks = "true"
To the Config Name = "Release"
section, but this doesn’t appear to work. Any thoughts?