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
Object Method Types When declaring an object method, it can be defined as one of three types: static, virtual, or dynamic. Each one has its strengths and weaknesses. Static methods do not gain the benefits of inheritance or polymorphism, one of the cornerstones of object-oriented programming. Virtual and dynamic methods both allow for inheritance and polymorphism, but the way in which applications access these methods is implemented differently. Without expounding on the inner workings of Delphi too greatly, virtual methods create an entry in a Virtual Method Table that is stored with each object. Dynamic methods, on the other hand, use a different method call-dispatching algorithm. Where dynamic methods are optimized for code size, virtual methods are optimized for speed. However, static methods are the fastest of all, since they are called directly with no need for method dispatching or VMT lookups. In general, try to use static methods as often as possible, but definitely use virtual instead of dynamic when using object-oriented programming techniques. Variants The variant data type is another new Delphi addition that makes certain programming practices incredibly easy. Using the variant type is almost essential when performing OLE or COM programming. However, because of its abilities to store just about any type of data, inexperienced programmers may be tempted to use only variables of type variant so as to avoid any data type incompatibilities. Unfortunately, because of its flexibility, the variant data type is very slow and should be avoided in high-performance code. With the variant being a 16-byte structure, it also wastes space. Unless you are doing some sort of OLE programming, avoid variants and use native data types. Listing 10-3: Variants versus native types
    procedure TForm1.Button1Click(Sender: TObject);

    var

      iCount: Integer;

      Junk: Variant;

      Junk2: Integer;

      StartTime,

      EndTime: LongInt;

    begin

      {turn optimization off}

      {$O-}

      {begin recording the time}

      StartTime := timeGetTime;

      {perform some standard task using a variant data type}

      Junk := 0;

      for iCount := 0 to 100000 do

      begin

        Junk := Junk + 1;

      end;

      {record the ending time...}

      EndTime := timeGetTime;

      {...and display the elapsed time}

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

      {begin recording the time}

      StartTime := timeGetTime;

      {perform the same function using a native data type}

      Junk2 := 0;

      for iCount := 0 to 100000 do

      begin

        Junk2 := Junk2 + 1;

      end;

      {record the ending time...}

      EndTime := timeGetTime;

      {...and display the elapsed time}

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

    end;
String Parameters An entire chapter could be written on the internal operations performed when Delphi works with strings. Both string and variant local variables within a function or method require prologue and epilogue code to be generated around the function to initialize and deinitialize the variable. Temporary storage variables may be generated when passing string results from one function as the parameter to another (such as passing the result of an IntToStr directly as a parameter), further increasing the generated code. Variant and string local variables automatically generate a stack frame within a function, defeating register optimizations. In general, avoid creating small utility routines that work on or use strings. If necessary, string or variant data should be processed in fewer, large routines that do as much as possible. Never use string variables or parameters to process information where an integer variable or parameter could accomplish the same task. Data Types The data types used by your application will impact its overall performance. Certain mathematical functions perform faster using certain data types; indeed, some data types are incredibly slow by comparison. In general, you’ll achieve the greatest performance when using native data types, such as integer. The MathTest example on the CD in the directory for this chapter can be used as a benchmark for testing execution speed of different operations on different data types. All of the floating-point and integer data types are tested, and though the exact execution times will vary from machine to machine, it is easy to see which data types perform better under certain circumstances than others. ### General Optimization Techniques We gain a lot of benefit from the automatic optimization that Delphi provides. We can also improve performance by being aware of the inner workings of certain Delphi code constructs. However, we should also be aware of general coding practices that can be used to improve performance in any language. #### Loop Unrolling It is very common for the point of execution within an application to jump from one point to another during the course of execution. For example, an If..Then statement causes the point of execution to skip some instructions based on the expression value. The time required for the execution point to change a single time is minimal. However, when the execution point jumps around repeatedly, these minimal time increments can accumulate. The biggest offenders in this category are loops, such as For..Next, While..Do, and Repeat..Until. Applications typically revolve around looping constructs such as these, performing the same functions on large amounts of data. This results in the execution point changing repeatedly. The amount of code and the task it performs within loops are prime targets for optimization. However, one technique you can use to improve loop performance is to unroll it. The concept of unrolling a loop is simple. Instead of performing one block of operations several times, perform several blocks of the same operations a fewer number of times. For example, if you have a loop that performs one operation 10,000 times, try performing 10 of those operations within the loop, and reduce the loop to run only 1,000 times. This will reduce the number of execution point jumps by an order of magnitude, and can dramatically improve overall performance. The following example illustrates this technique. Listing 10-4: Unrolling a loop
    procedure TForm1.Button1Click(Sender: TObject);

    var

      StartTime,

      EndTime,

      iCount: Integer;

      Accum: Real;

    begin

      {turn optimization off}

      {$O-}

      {initialize our variable and start tracking the time}

      Accum := 0;

      StartTime := timeGetTime;

      {perform some task many, many times}

      for iCount := 0 to 999999 do

        Accum := Accum + 0.5;

      {record the ending time...}

      EndTime := timeGetTime-StartTime;

      {...and display the elapsed time}

      Label1.Caption := ‘Regular loop time: ’+IntToStr(EndTime);

      {rest the variable and start tracking time}

      Accum := 0;

      StartTime := timeGetTime;

      {perform the same task as before, but this time repeat the task several

       times within the loop, and adjust the number of loops accordingly. note

       that the task is performed the same number of times as before, but now

       we’ve got an order of magnitude less jumps}

      for iCount := 0 to 99999 do

      begin

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

        Accum := Accum + 0.5;

      end;

      {record the ending time...}

      EndTime := timeGetTime-StartTime;

      {...and display the elapsed time}

      Label2.Caption := ‘Unrolled loop time: ’+IntToStr(EndTime);

    end;
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.