Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
## CHAPTER 10 Optimization Techniques This chapter covers the following topics: • Optimization theory • Delphi-specific optimization techniques • General optimization techniques • Additional optimization considerations The technique of optimizing code has been elevated to an art form. With today’s more advanced hardware, operating systems, and compilers, typically only the more experienced programmers will be relegated the duty of optimization. One must be intimately familiar with the workings of these three elements to truly be a master optimizer. However, there are several general techniques that are well publicized that can dramatically increase the speed at which an application runs, and you don’t have to eat, sleep, and breath assembly code to use them. Fortunately, Delphi helps a lot in the optimization department. There are also a number of Delphi-specific code traps that can dramatically slow down your applications. Optimization is a very broad topic, and there are several books that examine it exhaustively. In this chapter, we will examine a number of both Delphi-related optimization techniques and some general techniques that can be applied in almost any programming language.
| Note: You should run the examples in this chapter with optimization turned off (under Project | Options | Compiler). The example code is somewhat simplistic, and Delphi’s internal optimizations are usually so good that they can further optimize the code. Running the examples with optimization turned off gives you a better idea as to how the illustrated optimization will benefit application performance in a real-world situation. Also note that because the examples are simplistic, the loops within them are generally repeated more times than what would normally be encountered.
### Optimization Theory While optimization can be considered more an art than a science, there are a few general optimization rules that everyone should follow. The most important step in optimization is knowing where to optimize. After you’ve determined where the bottlenecks are in application execution, the next step is to evaluate the problem and determine how to optimize the code. You could take a guess at which part of your code is the slowest, but this method will most likely result in wasted time and increased frustration. The best course of action would be to employ a profiler to time program execution. Profilers generally report the number of times a particular function was called and the average length of execution. Using a profiler can quickly highlight the bottlenecks in an application, indicating a general location where optimization would be most effective. The freeware Delphi profiler GpProfile is an excellent profiling tool for all 32-bit versions of Delphi, and it comes with source code. At the time of this writing, it is available at http://members.xoom.com/primozg/gpprofile/ gpprofile.htm. Additionally, several Delphi tool vendors are working on retail versions of Delphi profilers, which should be available by the time this book reaches store shelves.
| profiler: A profiler is an application that typically measures application execution time. The level at which an application is timed usually varies, from timing the execution of individual lines to the execution time of functions, procedures, or the overall application.
In general, it is best to ignore optimization until the application is almost complete. Trying to write optimized code from the outset can be very distracting. Concentrate on actually getting the application to run first. Chances are that a developer could spend several hours optimizing a piece of code that is ultimately replaced midway through development. Optimizing code as a last step in the development process ensures that the time will be well spent. #### Timing Code In the absence of a profiler, there are several techniques a Delphi programmer can employ to time the execution of functions and methods. The one employed by the examples in this book involves the use of the timeGetTime function. The timeGetTime function retrieves the time that has elapsed since Windows was started, in milliseconds. Under Windows 95, this has a precision of 1 millisecond. Under Windows NT, the default precision is 5 or more milliseconds, but this can be adjusted by calling the timeBeginPeriod and timeEndPeriod functions.
| Note: You must include MMSystem in the Uses clause of any unit using the timeGetTime function.
Timing a function involves only three steps: recording the current value of timeGetTime in a variable, running the function code, and then again recording the current value of timeGetTime. The difference of these two values equals the total function execution time, as the following example illustrates. Listing 10-1: Using timeGetTime to time function execution
    procedure TForm1.Button1Click(Sender: TObject);

    var

      StartTime,

      EndTime: LongInt;

    begin

      {start tracking the time}

      StartTime := timeGetTime;

      {code to be timed goes here}

      {record the ending time}

      EndTime := timeGetTime;

      {the difference between the starting and ending times gives

       us the overall time required to execute the timed code}

      Label1.Caption := ‘Elapse Time: ’+IntToStr(EndTime - StartTime);

    end;
The timeGetTime function should be as accurate as required for just about any profiling needs. However, if more accuracy is required, the QueryPerformanceCounter and QueryPerformanceFrequency functions can be used. These functions give the developer access to the high-resolution performance counter that is present in just about every computer manufactured since the 486 was cutting-edge technology. QueryPerformanceFrequency returns the number of counts per second that the high-resolution timer records, and QueryPerformanceCounter returns the current count. Bear in mind, however, that these functions are useful only for timing very short periods, and cannot be used to time anything that executes for more than one second. #### Examining the Algorithm Once the bottleneck has been found, the first step in optimizing the code should be to reevaluate the algorithm. Examining the algorithm embodied by the code and finding a better algorithm will typically result in improved performance over that gained by any one particular optimization technique described below. The classic example is the bubble sort versus the binary sort. Both algorithms achieve the same result—a sorted list. However, the binary sort method is much faster than the bubble sort. Had a developer spent time employing various specific optimization techniques such as using assembly language or lookup tables, the performance of the original code may have been improved, but most likely would have resulted in a lot of wasted time and effort.
Previous | Table of Contents | Next

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.