Improve the compilation speed of c ++ builder by pre-compiling header files

Source: Internet
Author: User
Improve the compilation speed of c ++ builder by pre-compiling header files

C++ Builder is one of the fastest C ++ compilers. It can be said that it is also the fastest win32C ++ compiler. In addition to the speed, the performance of C ++ builder is also based on other C ++ compilers. However, many delphi programmers still cannot handle the compilation speed of c ++ builder projects. Indeed, delphi is much faster than Ren and c ++ compilers. Delphi may not be able to compile a small project within one second. A large project is usually compiled within five seconds.

Why is delphi so much faster than c ++ builder? Is there a way to compile the speed of c ++ builder? This article explains why C ++ compiler is slow and introduces a simple method to reduce the Compilation Time of c ++ builder.

Why is c ++ compiler slow?
How do c ++ builder users Reduce Compilation Time by pre-compiling header files?
Describes how to pre-compile header files based on VCL visual Projects
Optimize the use of pre-compiled header files by c ++ builder
Conclusion
Notes

Why is c ++ compiler slow??

In C ++, you can only use predefined or pre-declared functions. What does this mean? Let's look at A simple example. function A () calls function B (). function A () can only call function B () before its prototype or function body is. The following example illustrates this:

// Declaration or prototype for B
Void B ();

Void ()
{
B ();
}

// Definition, or function body of B
Void B ()
{
Cout <"hello ";
}
Without the prototype of B (), this code will not be compiled unless the function body of function B () is moved before function.
For the compiler, the function prototype is very important. When you run a program, the compiler inserts appropriate code to call the program. The compiler must know how many parameters need to be passed to the function. You also need to know whether the function parameter should be in the stack or in the register. In general, the compiler must know how to generate the correct code to call this function, which requires the compiler to know the previously declared or defined called function.
To simplify the prototype of a function or class, C ++ provides a # include command. # Include: allows the source file to locate the function prototype in a header file before the function prototype is called. # Include commands are important in win32C ++ programming. The prototype of the c rtl function is included in the standard header file set. The prototype of win32API is all in the header file set provided by Microsoft, and the classes and functions in VCL are in the header file released with C ++ builder. Without this, you can hardly do anything.
The header file provides a method that allows programmers to easily manage to perform C ++ type checks, but it also brings a lot of cost. When the compiler runs a # include command, it opens the header file and inserts it into the current file. Then, the compiler analyzes the contained files like the compiled files. What happens when the included file contains other header files? The compiler still inserts the file and analyzes it. Imagine what if 10, 20, or even 100 files are included? Although this number of contained files sounds a lot, it is not impossible to add the window sdk header file and all the vcl header files.
Here is an example of how the compiler expands and translates included files. This is a simple console program that I created using console wizard. To test the code, disable the pre-compiled headers option in options-project-compiler.

// Include some standard header files
// Contains some standard header files
# Include <stdio. h>
# Include <string. h>
# Include <iostream. h>
# Include <windows. h>

# Pragma hdrstop
# Include <condefs. h>

//-----------------------------------------------
Int main ()
{
Printf ("Hello from printf./n ");
Cout <"Hello from cout" <endl;
MessageBeep (0 );
Return 0;
}
When you use c ++ builder to compile a project, the compilation progress dialog box shows that the project contains 130,000 lines of code. 0.13 million rows! What's going on? There are only about four lines of code in the source file, which are included in stdio. h, string. h, iostream. h, windows. h, and the header files contained by these four header files.
Okay. Now let's take a look at what happens when the project contains multiple cpp files. Stop compiling the project and add an existing file to the project. Add a simple function to the second file. Call the new function in the first file.
//-------------------------------------------------------
// UNIT1.CPP
# Include <stdio. h>
# Include <string. h>
# Include <iostream. h>
# Include <windows. h>
# Include "Unit1.h" // prototype A () in unit1.h

# Pragma hdrstop

Void ()
{
Printf ("Hello from function A./n ");
}
//-------------------------------------------------------

//-------------------------------------------------------
// PROJECT1.cpp
# Include <stdio. h>
# Include <string. h>
# Include <iostream. h>
# Include <windows. h>
# Include "Unit1.h"

# Pragma hdrstop
# Include <condefs. h>

//-------------------------------------------------------
USEUNIT ("Unit1.cpp ");
//-------------------------------------------------------
Int main ()
{
Printf ("Hello from printf./n ");
Cout <"Hello from cout" <endl;
A ();
MessageBeep (0 );
Return 0;
}
//-------------------------------------------------------
Now, compile the project. If you disable the pre-compiled header file option before compilation, after compilation, you will find that the compilation progress dialog box displays a total of 260,000 lines of code. As you can see, the compiler has to process the same header file set contained in both files. In the previous example, the compiler processed more than 0.13 million lines of code produced by these header files. The second file allows the compiler to process the same 0.13 million lines of code, totaling 0.26 million lines. It is hard to imagine how fast the number of rows will grow in a big job. Processing these same header files over and over again greatly increases the Compilation Time.

How does C ++ Builder pre-compile the header file to reduce the Compilation Time?
Borland engineers realized that they could design a compiler that does not process the same header file over and over again to reduce Compilation Time. Therefore, Borland c ++ 3.0 introduces the pre-compiled header file concept. The solution is simple. When the compiler processes a set of header files in the source file, it stores the compiled image files on the disk, when other source files reference the same set of header files, the compiler directly reads the compiled files instead of analyzing them again.
Modify the console program to see how the pre-compiled header file reduces the Compilation Time. The Code itself does not need to be modified. Just select the pre-compiled header file option in the project option. Select Options-Project-Compiler and select Use pre-compiled headers or Cache pre-compiled headers. Enter PCH. CSM in the pre-compiled header file name column. After the change, re-compile the project.
Pay attention to the compilation progress dialog box during compilation. You will find that the compiler processes 130,000 lines of code when compiling project1.cpp, while UNIT1.cpp only processes 20 lines of code. When the compiler analyzes the first source file, it generates an image that predicts the compilation of the header file, which is directly used to increase the compilation speed when processing the second file. Imagine how much performance will increase when the number of source files is not 2 but 50!

Description of precompiled header files in the vcl gui Project
By pre-compiling header files, the previous example reduces the Compilation Time by at least 50%. This is just a simple console program with no functions. What will happen to you in the VCLGUI program? By default, c ++ builder automatically opens the pre-compiled header file option of the project. However, it only preprocess vcl. H files. This header file can be found at the top of the source file of any form.

# Include <vcl. h>
# Pragma hdrstop
# The pragma hdrstop command notifies the compiler to stop generating precompiled images. The # include statement before the hdrstop command will be pre-compiled, and the later statement will not.

When vcl. h is pre-compiled, how many header files are pre-compiled? You can check vcl. h and see that it contains another header file named vcl0.h. If you have not changed the default settings of C ++ builder, vcl0.h contains a group of vcl header files, which are:

// Core (minimal) VCL headers
//
# Include <sysdefs. h>
# Include <system. hpp>
# Include <windows. hpp>
# Include <messages. hpp>
# Include <sysutils. hpp>
# Include <classes. hpp>
# Include <graphics. hpp>
# Include <controls. hpp>
# Include <forms. hpp>
# Include <dialogs. hpp>
# Include <stdctrls. hpp>
# Include <extctrls. hpp>

This is a small part of repeated header files. Maybe it is only a set of header files commonly used in large and medium-sized projects. Vcl0.h also allows you to pre-compile more header files by defining conditions (# define. You can use # define a variable called INC_VCLDB_HEADERS to pre-compile the database header file. Similarly, you can define INC_VCLEXT_HEADERS to pre-compile the extension control (Extra controls) of c ++ builder ). If you also define INC_OLE_HEADERS, C ++ builder will pre-compile some sdk com header files. These definitions should be placed before the # include vcl. h Statement.
# Define INC_VCLDB_HEADERS
# Define INC_VCLEXT_HEADERS
# Include <vcl. h>
# Pragma hdrstop
Note: If you want to use these functions, make sure to add the two # define statements to each cpp file, even files that do not use databases or extended controls. The reason will be discussed later.

Use pre-compiled header files to optimize c ++ builder.

The default pre-compiled header file setting does reduce the Compilation Time. You can prove this by opening or disabling the option of precompiled header files to fully compile a large project. This section aims to further reduce the Compilation Time by improving the method of pre-compiling header files. Here I will talk about two technologies.
Before discussing these two technologies, it is necessary to understand how c ++ builder decides whether to use an existing pre-compiled header file image when compiling the source program. C ++ builder will generate a unique pre-compiled header file image for each source file in your project. These images are stored in a file on the hard disk. The compiler will reuse an image file when two source files use the same pre-compiled header file image. This is very important. When two source files contain the same header file, the pre-compiled header file image will be used. Then they must include these header files in the same order. Simply put, the # pragma hdrstop command of the source file must be identical. The following are some examples:

Example 1: Pre-compiled header file image Mismatch
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Include <stdio. h> # include <iostream. h>
# Pragma hdrstop

Example 2: Pre-compiled header file image Mismatch
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Include <stdio. h> # include <stdio. h>
# Include <iostream. h> # pragma hdrstop
# Pragma hdrstop

Example 3: Pre-compiled header file image Mismatch
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Include <stdio. h> # pragma hdrstop
# Pragma hdrstop # include <stdio. h>

Example 4: Pre-compiled Image Matching
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Include <stdio. h> # include <stdio. h>
# Include <string. h> # include <string. h>
# Include <iostream. h> # include <iostream. h>
# Include <windows. h> # include <windows. h>
# Include "unit1.h" # include "unit1.h"
# Pragma hdrstop

Example 5: Pre-compiled Image Matching
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Define INC_VCLDB_HEADERS
# Define INC_VCLEXT_HEADERS
# Include <vcl. h> # include <vcl. h>
# Pragma hdrstop

# Include "unit1.h" # include "unit2.h"

Example 6: Pre-compiled image Mismatch
//--------------------//--------------------
// UNIT1.CPP // UNIT2.CPP
# Define INC_VCLDB_HEADERS # include <vcl. h>
# Define INC_VCLEXT_HEADERS # pragma hdrstop
# Include <vcl. h>
# Pragma hdrstop

When the compiler processes a source file with unmatched pre-compiled images, a new image is generated. See example 2 above. Although stdio. h has been compiled in unit1.cpp, it still needs to be compiled in unit2. Only the pre-compiled image compiler can be used in multiple files to reduce the Compilation Time.
This is the basis of the technology I mentioned. Pre-compile as many header files as possible, and ensure that the same pre-compile image is used in each source file.

Technology 1:
The first technique is to add the number of header files contained in vcl. h by defining two conditions in each source file. Open each cpp file in the project, including the project file, and change the first two lines as shown below.
# Define INC_VCLDB_HEADERS
# Define INC_VCLEXT_HEADERS
# Include <vcl. h>
# Pragma hdrstop

If you do not like this method, you can enter INC_VCLDB_HEADERS and INC + VCLEXT_HEADERS in the Project-Options-Directories/Conditional condition definition column to achieve the same purpose.
You may also want to insert some common c rtl header files such as windows. h. Make sure that they are inserted before hdrstop pragma and in the same order.

# Define INC_VCLDB_HEADERS
# Define INC_VCLEXT_HEADERS
# Include <vcl. h>
# Include <windows. h>
# Include <stdio. h>
# Pragma hdrstop

Technology 2:
Technology 1 works well, but it is not flexible. If you want to add a new header file to the visually compiled header file list, you need to modify each source file in your project. In addition, technology is prone to errors. If you mess up the order of inclusion, you will only get worse, not better.
Technology 2 handles some shortcomings of Technology 1. You can create a huge header file to include all the header files used in your project. This header file contains the header file of VCL, the header file of window SDK, And the RTL header file. Of course, you can also include some header files of the created form, but you will know that you should not pre-compile some frequently modified files (view notes: do not pre-compile the changed header file)

The following is an example of a file:

//---------------------------------------------------------
// PCH. H: Common header file
# Ifndef PCH_H
# Define PCH_H

// Include every VCL header that we use
// Cocould include vcl. h instead
# Include <Buttons. hpp>
# Include <Classes. hpp>
# Include <ComCtrls. hpp>
# Include <Controls. hpp>
# Include <ExtCtrls. hpp>
# Include <Forms. hpp>
# Include <Graphics. hpp>
# Include <ToolWin. hpp>

// Include the c rtl headers that we use
# Include <string. h>
# Include <iostream. h>
# Include <stdio. h>

// Include headers for the 3rd party controls
// TurboPower System
# Include "StBase. hpp"
# Include "StVInfo. hpp"

// Our custom controls
# Include "DBDatePicker. h"
# Include "DBRuleCombo. h"
# Include "DBPhonePanel. h"

// Object Repository header files
# Include "BaseData. h"
# Include "BASEDLG. h"

// Project include files
// Pre-compile these only if PRECOMPILE_ALL is defined
# Ifdef PRECOMPILE_ALL
# Include "About
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.