C++Builder 5 Developers Guide

   

The C++Builder compiler is fast! It compiles C++ code almost twice as fast as the GNU C++ compiler and is comparable in speed to the Microsoft Visual C++ compiler. If you've used Delphi before, and you think that the C++Builder compiler takes much longer to compile a similar size application, you're right. The relatively slow compilation speed of C++ when compared to Delphi's Object Pascal is because of several reasons:

In general, C++ provides more flexibility in program design than Delphi's Object Pascal. However, this comes at the expense of compile time and in some cases code readability. There are several simple methods you can employ to speed up your C++Builder compile times. The most dramatic improvement can be achieved by using precompiled headers. This and other methods are described in the following sections.

Precompiled Headers

Precompiled headers are presented as a set of options on the Compiler tab of the Project Options dialog. When enabled by checking either Use Precompiled Headers or Cache Precompiled Headers, the compiler stores a compiled binary image of header files included in the various units in a disk-based file ( vcl50.csm in the C++Builder lib directory by default). Subsequent use of the same sequence of header files in another unit dramatically speeds up that unit's compile time by using the header files previously compiled. Selecting Cache Pre-Compiled Headers causes the compiler to load the precompiled headers in memory to further speed up the compile process.

The #pragma hdrstop directive in a unit causes the compiler to stop generating precompiled headers at that point. It is important to note that the order of the header files before the #pragma hdrstop directive in each unit is significant. Changing the order of the header files in two separate units can change the code resulting from those header files in each unit. Therefore, this requires both lists of header files to be compiled and stored separately as precompiled header groups.

Header files after the #pragma hdrstop directive are processed each time the unit is compiled. Typically, you should include header files common to two or more units before this directive so that they are compiled once only. Include all header files specific to each unit after the directive. By doing this, we are trying to get the most common match between header file lists in each unit to obtain the maximum benefit from this option.

The IDE automatically inserts the #pragma hdrstop directive in new units and places VCL header files included before the directive and unit-specific header files after the directive. A good example of header file grouping and order is shown in the top section of the fictional units LoadPage.cpp and ViewOptions.cpp in Listings 2.3 and 2.4.

Listing 2.3 Precompiled Header File Group in LoadPage.cpp

// // LoadPage.cpp #include <vcl.h> #include <System.hpp> #include <Windows.hpp> #include "SearchMain.h" #pragma hdrstop #include "LoadPage.h" #include "CacheClass.h" // // Code here...

Listing 2.4 Precompiled Header File Group in ViewOptions.cpplisting

// // ViewOptions.cpp #include <vcl.h> #include <System.hpp> #include <Windows.hpp> #include "SearchMain.h" #pragma hdrstop #include <Graphics.hpp> #include "ViewOptions.h" // // Code here...

By effectively grouping header files included in each unit and using precompiled headers, you can often see compile speeds increase up to 10 times!

NOTE

For information on speeding up compile times even further using precompiled headers, there is an excellent article on the BCBDEV Web site at http://www.bcbdev.com/ under the Articles link.

Other Techniques for Speeding Up Compile Times

Other techniques can be used to speed up compile times. They aren't as effective as using correctly grouped precompiled headers, but they are worth considering if compile speed is very important, particularly on large projects.

You should be careful about which header files are included in your units. Compiling unnecessary code is a waste of precious compile time, so in general you should not include unused header files. However, if you have included an unused header file in a unit to preserve header grouping when using precompiled headers, leave it in. Also, avoid changing header files too often. Each time you change a header file, the precompiled header groups that use this header file must be regenerated.

Use Make instead of Build . When Make is selected, the compiler attempts to detect and compile only the source files that have been modified since they were last compiled. Build , on the other hand, will recompile every source file in the project. Obviously, Build will take more time than Make , but there are times where Build is required.

Build is recommended after changing project options and when files are checked out or updated from a version control system. You should also use Build when compiling a release version of your application. This could be a debug or beta build going to testers or the final version to ship.

You should uncheck the Don't Generate State Files option on the Linker tab of Project Options. This will speed up subsequent compiles (particularly the first compile when reopening the project and when working with multiple projects in the IDE) as the linker saves state information in a file.

If you are not in a debugging phase for the project, disable all debugging options by selecting the Release button on the Compiler tab of Project Options and uncheck Use Debug Libraries on the Linker tab. If you do not yet need to compile a release version of the application, set Code Optimization on the Compiler tab of Project Options to None and uncheck Optimization in the Code Generation section on the Pascal tab.

It is important to look at the application structure and consider using packages or DLLs for modular parts , particularly in large projects. Both Make and Build will be considerably faster.

If you are not using floating-point math in your applications, checking None in the Floating Point group of the Advanced Compiler tab will speed up the link time slightly because the floating-point libraries will not be linked with your application.

These are things you can do within C++Builder and your code to minimize compile times. However, an important consideration is the computer hardware you are using. A software development system such as C++Builder requires higher-than-average system specs for CPU speed, RAM, and disk speed. Increasing these will yield a faster compile. In general, you should place slower IDE peripherals (such as an older CD-ROM drive) on a separate IDE controller from the hard drive. Defragmenting your hard drive might also slightly improve the compile time.

On multiprocessor (SMP) machines you can take advantage of all processors by invoking compilation of several modules simultaneously . The Borland MAKE utility provided does not support this directly, but you can write a script to run individual MAKE s of separate modules simultaneously. Alternatively, you can use the free GNU Make with the -j [jobs] command-line switch for parallel execution. You can get GNU Make for Windows from http://sourceware.cygnus.com/cygwin/.

Download the full Cygwin distribution, or at least the cygwin1.dll and make.exe files. For documentation, see http://www.gnu.org/software/make. To use GNU Make in C++Builder 5 and above, you'll need to export a makefile, either from the Project menu in the IDE or using the BPR2MAK.EXE command-line utility, because the project file is now stored in XML format. See BPR2MAK.EXE in the online help index for more information.

Finally, it probably doesn't need to be said that you should close other applications when working with C++Builder, particularly those that are memory or CPU intensive . If you're getting low on memory, things will certainly slow down considerably. I've also found that development on Windows NT and above is more responsive than Windows 95/98 (and provides a better debugging environment).


   
Top

Категории