Understanding Optimization

See Also

Optimization could be thought of as both a science and an art. The science is the techniques of optimization; the art is determining where and when optimizations should be applied. By definition, optimization is "the process of producing more efficient (smaller and/or faster) programs through selection and design of data structures, algorithms, and instruction sequences."

It is a common misconception that optimization is process that takes place at the end of the development cycle. To create a truly optimized application, you must be optimizing it while you are developing it. You choose your algorithms carefully, weighing speed against size and other constraints; you form hypotheses about what parts of your application will be fast or slow, large or compact; and you test those hypotheses as you go.

The first step in the process of optimization is determining your goal. You can optimize your program for many different characteristics:

Rarely, however, can you optimize for multiple characteristics. Typically, an approach that optimizes size compromises on speed; likewise, an application that is optimized for speed is often larger than its slower counterpart. For this reason, recommended optimization techniques in one area may directly contradict suggestions in another.

It’s important to note that optimization is not always completely beneficial. Sometimes the changes you make to speed up or trim down your application result in code that is harder to maintain or debug. Some optimization techniques contradict structured coding practice, which may cause problems when you try to expand your application in the future or incorporate it into other programs.

In designing an optimization strategy for your application there are three things to consider: knowing what to optimize, knowing where to optimize, and knowing when to stop.

Knowing What to Optimize: Understanding the Real Problem

If you don’t start with a clear goal in mind, you can waste a lot of time optimizing the wrong things. Your goal should be based on the needs and expectations of the user. For example, speed might be a major concern for calculating sales tax in a point-of-sale application, whereas application size would be most important for an application that will be downloaded via the Internet. The key to developing a good optimization strategy is to understand the real problem that the optimization will address.

Although your optimization strategy will target a specific goal, it helps to think about optimization throughout the development process. When writing code, you can learn a lot by simply stepping through your code and thinking carefully about what's actually happening. You may forget that setting properties causes events to occur, and if there is a lot of code in those event procedures, an innocuous line of code can cause a tremendous delay in your program. Even if your primary goal is size, speed optimizations can sometimes be implemented without adding to code size.

Knowing Where to Optimize: Maximum Benefit with Minimum Effort

If you’re like most developers, you can’t afford the time to optimize everything in your application. It’s sometimes useful to think of having an "optimization budget." After all, added time equates to added development cost. Where can you spend your time to get a maximum return on your investment? Obviously you want to focus on the areas that seem to be the slowest or fattest, but to maximize the results of your efforts, you want to concentrate on code where a little work will make a lot of difference.

For example, if speed is your primary goal, the bodies of loops are usually a good place to start. Whenever you speed up the operations inside a loop, that improvement is multiplied by the number of times the loop is executed. For loops with a large number of iterations, just one less string operation in the body can make a big difference. The same principle applies to frequently called subroutines as well.

Knowing When to Stop: Weighing the Results

Sometimes things aren't worth optimizing. For example, writing an elaborate but fast sorting routine is pointless if you're only sorting a dozen items. It’s possible to sort things by adding them to a sorted list box and then reading them back out in order. With large numbers of items this is horribly inefficient, but if there aren't a lot of items it is just as quick as any other method, and the code is admirably simple (if a bit obscure).

There are other cases where optimization is wasted effort. If your application is ultimately bound by the speed of your disk or network, there is little you can do in your code to speed things up. Instead you need to think about ways to make these delays less problematic for your users: progress bars to tell them your code isn't simply hung, caching data so they see the delays less often, yielding so that they can use other programs while they wait, and so on.

For More Information   See "Interrupting Background Processing" in "Responding to Mouse and Keyboard Events."