pch.htm
来自「C++builder学习资料C++builder」· HTM 代码 · 共 785 行 · 第 1/4 页
HTM
785 行
<font color="navy">// include every VCL header that we use</font>
<font color="navy">// could include vcl.h instead</font>
<font color="green">#include <Buttons.hpp></font>
<font color="green">#include <Classes.hpp></font>
<font color="green">#include <ComCtrls.hpp></font>
<font color="green">#include <Controls.hpp></font>
<font color="green">#include <ExtCtrls.hpp></font>
<font color="green">#include <Forms.hpp></font>
<font color="green">#include <Graphics.hpp></font>
<font color="green">#include <ToolWin.hpp></font>
<font color="navy">// include the C RTL headers that we use</font>
<font color="green">#include <string.h></font>
<font color="green">#include <iostream.h></font>
<font color="green">#include <stdio.h></font>
<font color="navy">// include headers for the 3rd party controls</font>
<font color="navy">// TurboPower System</font>
<font color="green">#include "StBase.hpp"</font>
<font color="green">#include "StVInfo.hpp"</font>
<font color="navy">// Our custom controls</font>
<font color="green">#include "DBDatePicker.h"</font>
<font color="green">#include "DBRuleCombo.h"</font>
<font color="green">#include "DBPhonePanel.h"</font>
<font color="navy">// Object Repository header files</font>
<font color="green">#include "BaseData.h"</font>
<font color="green">#include "BASEDLG.h"</font>
<font color="navy">// project include files</font>
<font color="navy">// pre-compile these only if PRECOMPILE_ALL is defined</font>
<font color="green">#ifdef PRECOMPILE_ALL</font>
<font color="green">#include "About.h"</font>
<font color="green">#include "mainform.h"</font>
<b>...</b>
<b>...</b> <font color="navy">// about 60 more files</font>
<b>...</b>
<font color="green">#include "validate.h"</font>
<font color="green">#endif</font>
<font color="green">#endif</font>
</pre>
<P>
Once you have the gigantic common header file ready, change every source file so it includes this file. I have chosen
to leave the original include statement for <TT>VCL.H</TT> intact. You might want to move <TT>VCL.H</TT> to the
common header file.
</P>
<pre>
<font color="navy">//-----------------------------------------------</font>
<font color="green">#include <vcl.h></font>
<font color="green">#include "pch.h"</font>
<font color="green">#pragma hdrstop</font>
</pre>
<P>
<B>Note:</B> After you add the include for <TT>PCH.H</TT> to every C++ source file, don't insert any more include
files prior to the <TT>#pragma hdrstop</TT>. Doing so will cause those C++ files to require a pre-compiled image that
does not match the pre-compiled image from other files.
<BR>
<H3>
<A NAME="results">Results</A>:
</H3>
<P>I am currently employing Technique 2 without defining <TT>PRECOMPILE_ALL</TT> on my current project. The project
is a medium sized client/server database program that consists of 113 C++ source files, most of which are forms or
datamodules. Using Technique 2, a full build of the project takes only 195 seconds. Of that 195 seconds, 40 seconds
are spent generating the pre-compiled header, and about 40 seconds are spent linking. In the remaining time, the compiler
translates 113 C++ source files. That's an average of one file per second. By way of comparison, the project takes
more than 30 minutes to build when no pre-compiled headers are used, and the project takes 18 minutes to build when
pre-compiled headers are used but Technique 2 is not utilized.
</P>
<P>
Incremental makes with Technique 2 are lightning fast when no header files have changed. The compiler does not bother
to regenerate the pre-compiled image on disk if no header files have changed. When this condition is met, an incremental
make takes only 1 or 2 seconds, because only the C++ source files that have changed need to be compiled. The compiler
spends all of its time compiling those files, instead of wasting its time compiling system header files. When a header
file does change, the speed of an incremental make depends on whether or not the <TT>PRECOMPILE_ALL</TT> flag was
defined.
</P>
</H3>
<P>
</P>
<H3>
<A NAME="notes">Notes:</A>
</H3>
<P>
<B>Don't pre-compile constant variables:</B> The compiler cannot pre-compile a header file if it contains a constant
variable that is assigned a value. For example, placing the following line in a header file can interfere with the
creation of a pre-compiled header image:
</P>
<pre>
<b>const</b> AnsiString strError <b>=</b> <font color="blue">"An Error Occurred!!!!!"</font><b>;</b>
</pre>
<P>
If you want to place const variables in a header file, create a separate header file to contain the constants and
don't pre-compile that file. Try to reduce the burden on the compiler by not allowing this header file to include
other files. Similarly, don't include this file from other header files if you can help it. If this seems like a
difficult task, you can use the <TT>extern</TT> keyword. Create a header file that contains <TT>extern</TT> prototypes
for your constants. Then create a <TT>CPP</TT> file that defines the constants (ie gives them a value).
</P>
<P>Note that the problem of const variables only occurs when you do define the <TT>PRECOMPILE_ALL</TT> flag.
When you do not define this flag, your own header files are not pre-compiled. If you don't pre-compile a header file,
then you can add constants to it without any problems. Also, <TT>#define</TT>'s do not present a problem, just const
variables (although I don't recommend that you switch back to <TT>#define</TT>'s).
</P>
<P>
<B>Don't pre-compile template headers:</B> This suggestion is based on empirical evidence. I have a template class with
several inline functions. The entire template class resides in a header file. The compiler was able to pre-compile this
header file, but I noticed that the pre-compiled image was always re-generated during an incremental make. I think this
has to do with the way templates are handled by the compiler. I can pre-compile the STL headers without any problems,
so I'm not sure what the problem is. I suggest that you go ahead and try to compile template headers, but pay close
attention to the compiler progress dialog. You may need to stop pre-compiling template headers if they cause problems.
</P>
<P>
<B>Keep an eye on the compiler progress dialog:</B> The compiler progress dialog tells you how well your pre-compiled
headers are working. When you employ Technique 2, you should see that the compiler takes a long time to compile the
first C++ source file in your project. The compiler generates the pre-compiled header image during compilation of the
first file in the project. During this time, you should see the line count on the compiler
progress dialog reach a huge number (100,000-500,000). Once the compiler moves on to other C++ files, the line count
should probably be between 20 and 1000 lines for each source file if you define the <TT>PRECOMPILE_ALL</TT> flag.
If you don't define this flag, the line count should stay under 15000 or so. Once the compiler finishes translating the
first file in the project, subsequent files should only take a second or two to compile.
</P>
<P>
If the compiler gets bogged down on one C++ file for more than 4 seconds, you probably have a source file whose
pre-compiled image doesn't match the image created by the common header file. The line count is another indicator. If
you see the line count sail up above 50,000 lines for one source file, it's a good indication that the compiler was
unable to apply the existing pre-compiled image to that source file.
</P>
<P>
<B>Don't pre-compile header files that change:</B> When using Technique 2, realize that any small change to a header
file will force the compiler to regenerate the pre-compiled image. Based on the test results, this could take from 20
seconds to a minute. If your header files change frequently, you may want pre-compile only system and VCL header files.
This is the purpose of the <TT>PRECOMPILE_ALL</TT> flag. It allows you to easily include or remove your header
files from the pre-compiled image.
</P>
<pre>
<font color="navy">//---------------------------------------------------------</font>
<font color="navy">// PCH.H: Common header file</font>
<font color="green">#ifndef PCH_H</font>
<font color="green">#define PCH_H</font>
<font color="navy">// include every VCL header that we use</font>
<font color="green">#include <Buttons.hpp></font>
<font color="green">#include <Classes.hpp></font>
<font color="navy">// include the C RTL headers that we use</font>
<font color="green">#include <string.h></font>
<font color="green">#include <iostream.h></font>
<font color="green">#include <stdio.h></font>
<font color="navy">// project include files</font>
<font color="navy">// pre-compile these only if PRECOMPILE_ALL is defined</font>
<font color="green">#ifdef PRECOMPILE_ALL</font>
<font color="green">#include "About.h"</font>
<font color="green">#include "mainform.h"</font>
<b>...</b>
<b>...</b> <font color="navy">// about 60 more files</font>
<b>...</b>
<font color="green">#include "validate.h"</font>
<font color="green">#endif</font>
<font color="green">#endif</font>
</pre>
<P>To pre-compile your own header files, add <TT>PRECOMPILE_ALL</TT> to the conditional defines line under
Project - Options - Directories/Conditional. If your header files change frequently, then don't add this
conditional define. When you don't pre-compile your own header files, a full build of your project will take a little
longer. However, when you make a change to one of your header files, an incremental make will be faster because the
compiler won't waste 20-60 seconds rebuilding the pre-compiled image.
</P>
I do not define <TT>PRECOMPILE_ALL</TT> for the project that I described in the Results section
because I found I was still changing my header files frequently, and incremental makes were taking more than 2 minutes.
The table below illustrates how the <TT>PRECOMPILE_ALL</TT> directive affects compile time. I timed how long a full
build took when the <TT>PRECOMPILE_ALL</TT> was defined. Then I made a small change to the header file for
my main form and performed an incremental make. Next, I repeated this process with the <TT>PRECOMPILE_ALL</TT>
value not defined. Here are the results.
</P>
<PRE>
Not defined (do not pre-compile my headers)
-------------------------------------------------------------
Full Build: 195 sec 408887 lines compiled
Inc Make : 28 sec 7 files affected: 27059 lines compiled
Defined (pre-compile my headers)
-------------------------------------------------------------
Full Build: 179 sec 255689 lines
Inc Make : 179 sec all files affected: 255689 lines
</PRE>
<P>
Notice that a full build is 16 seconds faster when I pre-compile my own header files, but look what happens when I do
an incremental make after changing a header file. The incremental make takes just as long as a full build. When you
pre-compile your own header files, the compiler rebuilds the pre-compiled image every time you change a header file.
Additionally, when the pre-compiled image changes, every file that depends on that image will be re-compiled as well.
So if you alter a header file, the entire project essentially gets rebuilt. When I do not pre-compile my own header
files, the pre-compiled image never gets rebuilt. This keeps the incremental make time down, 28 seconds compared to
179 seconds.
</P>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?