利用pre-compiled headers技术以加速编译速度--以Borland C++ Builder为例(四)

类别:编程语言 点击:0 评论:0 推荐:

利用pre-compiled headers技术以加速编译速度
--以Borland C++ Builder为例
(四)

本文作者:王森
台湾交通大学科技管理研究所
[email protected]

<编译器指令#pragma hdrstop之前只能放系统标头文件吗?>

    请大家回头看看在这之前所有被我们用来测试的程序原始文件。拿程序代码5来说,大家会发现,Unit2.cpp并没有放在编译器指令#pragma hdrstop之前,那幺是否代表笔者默认Unit2.cpp不能放在编译器指令#pragma hdrstop之前呢? 让我们来做个Project实验组,程序代码如下:

程序代码6-1:

Unit1.cpp
#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#include "Unit2.h"
#pragma hdrstop

#pragma argsused
int main(int argc, char* argv[])
{
    cout << "Hello World" ;
    return 0;
}

Unit2.h
#ifndef Unit2H
#define Unit2H

void test(void) ;
#endif

Unit2.cpp
#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#include "Unit2.h"
#pragma hdrstop

void test(void)
{
    printf("test") ;
}

然后我们试着编译看看。接着我们一个档案都不要删除,直接把Unit2.h与Unit2.cpp叫出来,把档案内容改成:
程序代码6-2:
Unit2.h

#ifndef Unit2H
#define Unit2H

void test(void) ;
void test1(void) ;
#endif

Unit2.cpp
#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#include "Unit2.h"
#pragma hdrstop

void test(void)
{
    printf("test") ;
}
void test1(void)
{
    printf("test1") ;
}
再重新使用make编译。

    同理,我们也做一组完全相同的Project当作对照组,档案内容几乎完全相同,除了我们把#include "Unit2.h"放回编译器指令#pragma hdrstop之后,我们也做跟上面实验组Project相同的测试:

程序代码7-1:
Unit1.cpp

#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#pragma argsused
int main(int argc, char* argv[])
{
    cout << "Hello World" ;
    return 0;
}

Unit2.h
#ifndef Unit2H
#define Unit2H

void test(void) ;
#endif

Unit2.cpp
#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
void test(void)
{
    printf("test") ;
}

程序代码7-2:
Unit2.h

#ifndef Unit2H
#define Unit2H

void test(void) ;
void test1(void) ;
#endif

Unit2.cpp
#include <iostream.h>
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
void test(void)
{
    printf("test") ;
}
void test1(void)
{
    printf("test1") ;
}

我们把这两次测试的结果列在下表
测试结果8: Unit2.h在#pragma hdrstop之前 Unit2.h在#pragma hdrstop之后 编译次数 编译行数 编译时间 编译次数 编译行数 编译时间 第一次(build)程序代码6-1 202245 8.29 第一次(build)程序代码7-1 202258 8.65 第二次(make)程序代码6-1 0 0.14 第二次(make)程序代码7-1 0 0.16 第三次(make)程序代码6-2 202253 9.16 第三次(make)程序代码7-2 65 1.68

    这个测试结果代表了什幺涵义呢? 

这个测试结果并非只有系统标头文件才能放在编译器指令#pragma hdrstop之前,程序设计师自己定义的标头档也可以。

在标头档小小的更动会造成整个程序原始文件从头到尾重新编译,也使得编译器重新产生新的cache檔(注意:编译器会覆盖具有相同预先编译标记的vcl50.#??档,而非重新产生。其实这样也无可厚非,否则Lib目录下就会有好多具有相同预先编译标记的cache文件,这样可就糟糕了!)

    在程序开发初期,程序标头文件常常会被修改,可是系统标头文件却几乎没有人会去动到他们,所以在整个系统的函式接口或数据结构尚未稳定之前,尽量先不要把程序设计师自己定义的标头文件放到编译器指令#pragma hdrstop之前。因为这幺一来,非但没有加速程序的编译速度,反而因为预先编译标记没有改变,可是标头档内容却变了,而迫使编译器每次都要重新编译这些标头档并产生新的cache檔(而且还要先删掉原先具有相同预先编译标记的cache文件,使得整体编译时间更长)。这个问题在我们的测试程序里并不明显,可是读者可以想象,如果今天我们是撰写GUI程序,我们常常要修改Form上的组件和事件处理函式,每次一修改,势必动到标头档(因为增添/删除组件,或是新增事件处理函式的时候都会让该Unit对应的标头档改变),如果我们的Project里头有好多Form,那事情可就不妙了!! 所以在此笔者的建议是:在程序设计初期,请先将这些程序设计师自行定义的标头文件移到编译器指令#pragma hdrstop之后(IDE所帮我们产生的Unit就是以此为预设情况),等到整个系统之中所有类别、函式接口、数据结构都大致底定的时候,再将这些标头文件移到编译器指令#pragma hdrstop之前,这样效果就会好很多

本文地址:http://com.8s8s.com/it/it29666.htm