Variants are convenient when you’re putting together a short program to display the ASCn character set or the ASCn values of the function keys, but otherwise, you should avoid variants in your code. They take up much more memory than other data types and can’t be processed immediately. When the compiler encounters them, it must find out their proper type, convert them to their type, and then use them in a calculation. For example, if adant holdsthe value 45, the compiler must convert it to a numeric value before using it in a numeric calculation or to a string before using it in a string operation. Some developers defend variants, pointing ou.t that they free the programmer from having to declare variables and use them consistently. TIley may give you some neat examples-mostly one-liners that normally could be implemented with two or three lines of code. If you’re trying to squeeze every drop of petfonnance ” from your application, avoid variants. Or, if you’re the type that to learn the hard way, use them and see for yourself. Let’s write some code that performs math calculations with variants and doubles. Place a COmma! d button on a Form, and then insert the following code in the button’s Click event handler.
Timing Math Operations,wlth Variats and Double
This subroutine declares the variables i/l, v2, and vCounter as Variants and the variables dl, d2, and dCouriter as Double and Long, respectively. Then, it performs the same calculations a million times. The calculations are really trivial.
The first time, the calculations are executed with the variant variables by using them as the loop counter. The same calculations are then repeated with double variables, using a long variable as the loop counter. The time required for the completion of each loop is then displayed on a message box. On a 166MHz Pentium, the loop with variants takes 24.500 seconds and the loop with the declared variables takes only 13.125 seconds. The declared variables loop is nearly twice as fast! This difference may become even greater for more complicated calculations. You may ask, “How many applications perform the same calculations a million. times?” It’s not as rare as you may think. Consider an image processing application or an application that generates fractals: the same calculations must be performed for each pixel in the image or in the Picture Box control where the fractal will be disp.la.yed . If you compile this application to native code, the results will favor the loop with the declared variables even more. To compile the application; follow these steps:
1. In the Project Properties dialog box, check the Compile to Native Code and the Optimize for Fast Code options.
2. Click the Advanced Optimizations button to open the Advanced Optimizations dialog box.
3. Check all the options to enable, all optimizations.
4. Now choose Pile >Make PROJECTl.EXE to generate the executable file (or use whatever name you’ve assigned to your project).
5. Minimize the Visual Basic window, locate the PROJECTl.EXE file, and run it. The times for the compiled application on the same computer are 17.578 seconds (for the loop with variants) and 6.977 seconds (for the loop with doubles)-two-anda- half times faster! Clearly, you must always declare your variables with their proper types. You will experience similar gains with strings versus variants.
Now let’s experiment with the optimization options to see what effect they have on speed. Go back to the Advanced Optimizations dialog box and clear the Allow Unrounded Floating-Point Operations option. This will tell the compiler to round the results of each operation in-between calculations, as if they were moved to memory. This will add a few cycles and-cause some loss in accuracy too (one wonders why this is even an option). If you·run the program again, the calculationswith the declared variables will take 6:703 seconds and those with variants will take 27.898 seconds. Iri shortrounding interIl1ediate results will have a profound effect on execution time. Any additional operation introduced by the compiler will affect your code’s speed adversely, especially if it’s applied to variants. The rounding of the values requires intermediate results to be moved from registers to memory and back, resulting in additional execution time. Registers can store numbers with greater accuracy than memory and you should enable this option in applications that perform lots of math operations.