Borland Online And The Cobb Group Present:


February, 1994 - Vol. 1 No. 2

Optimizing your code - Eliminating common subexpressions

xperienced C and C++ programmers are careful to write the smallest and fastest code they can. Sometimes speed is a greater factor than size, and other times it's the other way around.

Frequently, you can make both size and speed improvements to a program by creating temporary variables. Instead of evaluating the same expression multiple times, you can evaluate it once, store the result in a temporary variable, and then use that variable instead of repeating the expression. However, if you use the temporary variable later in the program, it may be unclear what that variable represents (particularly if the statements are very long).

Instead, you can intentionally reuse an expression and instruct the optimizer to create the temporary variable for you. In this article, we'll show you how to use the optimizer in the Borland C++ compiler to eliminate common subexpressions. By doing so, you'll create code that's efficient and readable.

Relying on the Optimizer

If you're trying to write an efficient program by eliminating repetitive expressions, you could turn the code

if((dataStructPointer->item * 5) < 10)
{
// some code here
}
else if((dataStructPointer->item * 5) > 30)
{
// some code here
}

into

int temp = dataStructPointer->item * 5;
if(temp  < 10)
{
// some code here
}
else if(temp  > 30)
{
// some code here
}

If your program called this code fragment frequently, you'd see an improvement in speed.

Unfortunately, the meaning of temp may not be obvious to others maintaining this project. In fact, temp may be confusing to you if it appears elsewhere in the code or if you're looking at it later.

If you reuse expressions freely, the code will be easier for you, or anyone else, to read and maintain. Then, you can enable common subexpression elimination to let the compiler decide if it's better to replace some of those expressions with a temporary variable.

To eliminate common subexpressions from an open file or project, you'll start from the Project Options dialog box and select the subtopic Specific from the topic Optimizations. Next, you'll select the Optimize Globally radio button in the Common Subexpressions group to perform this optimization globally. Or, select the Optimize Locally radio button in this group to eliminate common subexpressions locally. (See A closer look at subexpressions for a comparison of global and local subexpression elimination.)

Now when you recompile the project, the compiler will eliminate common subexpressions in the object files as necessary without affecting the source code itself. Let's apply this optimization to an example.

An Optimum Example

Launch the Borland C++ 4.0 Integrated Development Environment (IDE) and choose New Project... from the Project menu. When the New Project dialog box appears, enter OPTIMUM.IDE in the Project Path and Name entry field. Then, choose DOS Standard from the Platform combo box. Click the OK button, as shown in Figure A, to open the new project.


Figure A - The New Project dialog box creates a new project.

When the Project Manager window for OPTIMUM.IDE appears, choose Project... from the Options menu. In the Project Options dialog box, double-click on the topic Optimizations. Three subtopics will appear under Optimizations: Specific, Size, and Speed.

Select the subtopic Specific from the dialog box's Topics list. Then, click the Optimize Globally radio button in the Common Subexpressions group, as shown in Figure B.

Figure B - From the Project Options dialog box, you can tell the compiler to eliminate common subexpressions.

Click the OK button to save the new optimization settings. Until you change the optimization settings in the Project Options dialog box, the compiler will globally eliminate common subexpressions in the OPTIMUM project.

Double-click on the optimum[.cpp] file in the Project Manager window. When the OPTIMUM.CPP editor window appears, enter the source code from Listing A.


Listing A: OPTIMUM.CPP

struct DataStruct
{
   int item;
};

int main()
{  DataStruct* DataStructPointer =
        new(DataStruct);
   DataStructPointer->item = 10;

   int NewValue = 
        DataStructPointer->item * 2;

   if(NewValue < 30)
   {
      NewValue =
        DataStructPointer->item * 2;
   }
   else
   {
      NewValue = 
        5 * (DataStructPointer->item * 2);
   }

   delete DataStructPointer;

   return 0;
}

When you finish entering the code, choose Save from the File menu. Then, close the OPTIMUM.CPP editor window.

In the Project Manager window, click on optimum[.exe] with the right mouse button and choose Build Node from the pop-up menu, as shown in Figure C. The IDE will now compile the OPTIMUM project using common subexpression elimination.

Figure C - You can build the project using its pop-up menu in the Project Manager Window.

Now, reopen OPTIMUM.CPP by double-clicking on its name in the Project Manager window. When the editor window for the source file appears, you'll notice that all the repeated expressions remain intact. This is because the compiler eliminates common subexpressions only in the object files, not in the source files.

Conclusion

Writing efficient programs in C++ is a goal of most professional programmers. However, if you concentrate solely on code efficiency, you may create code that is difficult to read and maintain.

Instead of using your own temporary variables to optimize your C++ source code, you can let the Borland C++ compiler eliminate common subexpressions for you. You'll know that you're not creating unnecessary temporary variables, and you'll have an easier time reading your source code.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.