国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

通過(guò)預(yù)編譯頭文件來(lái)提高CB的編譯速度

2019-11-17 05:31:25
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
  C++ Builder是最快的C++編譯器之一,從編譯速度來(lái)說(shuō)也可以說(shuō)是最快的win32C++編譯器了。除了速度之外,C++builder的性能也在其它C++編譯器的之上,但許多Delphi程序員仍受不了C++builder工程的編譯速度。的確,delphi的速度要比任和c++的編譯器都要快好多。Delphi在編譯一個(gè)小工程的時(shí)候可能不到一秒,大的工程一般也在5秒鐘這內(nèi)編譯完成了。
  
  為什么delphi會(huì)比c++builder快這么多?是否有方法來(lái)c++builder的編譯速度?本文就講解了為什么C++的編譯器速度會(huì)慢,并且介紹了一個(gè)簡(jiǎn)單的方法來(lái)減少c++builder的編譯時(shí)間。

為什么c++編譯器的速度會(huì)慢?
c++builder 使用者怎么通過(guò)預(yù)編譯頭文件來(lái)減少編譯時(shí)間?
講解基于VCL可視化工程的預(yù)編譯頭文件方法
優(yōu)化c++builder對(duì)預(yù)編譯頭文件的使用
結(jié)論
注重事項(xiàng)



為什么c++編譯器速度慢?

  在C++中,你只能使用預(yù)定義或是預(yù)先聲明了的函數(shù),這意味什么?來(lái)看一個(gè)簡(jiǎn)單的例子,函數(shù)A()調(diào)用函數(shù)B(),函數(shù)A()只能在函數(shù)B()的原型或是函數(shù)體在A()之前才能調(diào)用它。下面的例子說(shuō)明了這一點(diǎn):

// declaration or PRototype for B
void B();

void A()
{
    B();
}

// definition, or function body of B
void B()
{
    cout << "hello";
}
  沒(méi)有B()的原型,這個(gè)代碼不會(huì)編譯通過(guò)的,除非函數(shù)B()的函數(shù)體移到函數(shù)A()之前。
  對(duì)于編譯器來(lái)說(shuō),函數(shù)的原型很重要。當(dāng)你運(yùn)行程序時(shí),編譯器都要插入恰當(dāng)?shù)拇a來(lái)調(diào)用程序。編譯器必需知道要有多少個(gè)參數(shù)傳給函數(shù)。也要知道函數(shù)的參數(shù)應(yīng)該在棧里還是在寄存器里。總而言這,編譯器必需知道怎么來(lái)產(chǎn)生正確的代碼來(lái)調(diào)用這個(gè)函數(shù),這就要求編譯器必需知道預(yù)先聲明或定義了的被調(diào)用的函數(shù)。
  為使函數(shù)或類的原型簡(jiǎn)單化,C++提供了一個(gè)#include 指令。#include代表答應(yīng)源文件在函數(shù)原型被調(diào)用的位置之前包含的一個(gè)頭文件中找到函數(shù)原型。#include 指令在win32C++編程中很重要。C RTL函數(shù)的原型都包含在標(biāo)準(zhǔn)的頭文件集中。win32API的原型全在微軟提供的頭文件集中,VCL中的類和函數(shù)的在原型則在隨C++builder發(fā)行的頭文件中。沒(méi)有這些,你幾乎做不了什么。
  頭文件提供了一種讓程序員很輕易治理的方式來(lái)執(zhí)行C++的類型檢查,但是也帶來(lái)了很大的代價(jià)。當(dāng)編譯器運(yùn)行到一個(gè)#include 指令時(shí),它會(huì)打開(kāi)這個(gè)頭文件并插入到當(dāng)前文件中,然后編譯器象分析已編譯的文件一樣來(lái)分析這些包含進(jìn)來(lái)的文件。當(dāng)被包含的文件中還包含有其它的頭文件時(shí)會(huì)怎么樣呢?編譯器仍會(huì)插入那個(gè)文件再分析它,想象一下,當(dāng)10、20甚至100個(gè)文件被包含時(shí)呢?盡管如此數(shù)量的包含文件聽(tīng)起來(lái)很多,但當(dāng)你加入window sdk頭文件和所有vcl頭文件時(shí),這并不是不可能的。
  來(lái)舉個(gè)例子說(shuō)明一下編譯器是如何展開(kāi)和翻譯被包含的文件的。這是一個(gè)我用console wizard建立的一個(gè)簡(jiǎn)單的控制臺(tái)程序。為了試驗(yàn)代碼,在options-project-compiler在把pre-compiled headers選項(xiàng)關(guān)掉。

// include some standard header files
//包含了一些標(biāo)準(zhǔn)的頭文件
#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;
}
  當(dāng)用c++builder編譯工程時(shí),編譯進(jìn)度對(duì)話框顯示工程中包含有130,000行代碼。13萬(wàn)行!怎么回事?源文件中只有大約四行代碼,這13萬(wàn)行都包含在stdio.h,string.h,iostream.h,windows.h和被這四個(gè)頭文件所包含的頭文件里。
  好,現(xiàn)在來(lái)看一下當(dāng)工程中包含多個(gè)cpp文件時(shí)情況是怎么樣的。停止編譯這個(gè)工程,再加一個(gè)已有的文件到這個(gè)工程中。在第二個(gè)文件中加一個(gè)簡(jiǎn)單的函數(shù)。再到第一個(gè)文件中來(lái)調(diào)用這個(gè)新函數(shù)。

//-------------------------------------------------------
// UN99v1.CPP
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <windows.h>
#include "Unit1.h"        // prototype A() in unit1.h

#pragma hdrstop

void A()
{
    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>

//-------------------------------------------------------
USEUN99v("Unit1.cpp");
//-------------------------------------------------------
int main()
{
    printf("Hello from printf./n");
    cout << "Hello from cout" << endl;
    A();
    MessageBeep(0);
    return 0;
}
//-------------------------------------------------------
  好,現(xiàn)在再來(lái)編譯這個(gè)工程。假如在編譯之前你關(guān)掉了pre-compiled頭文件選項(xiàng),當(dāng)你編譯完時(shí)你會(huì)發(fā)現(xiàn)編譯進(jìn)度對(duì)話框顯示共有260,000行代碼。可以看到,編譯器不得不把兩個(gè)文件都包含的相同的頭文件集都做處理。在前面的例子里,編譯器多處理了這些頭文件帶來(lái)的13萬(wàn)行代碼。第二個(gè)文件又讓編譯器處理了同樣的13萬(wàn)行代碼,總共26萬(wàn)行。不難想象在一個(gè)大工程里行數(shù)將會(huì)以什么速度增長(zhǎng)。一遍又一遍的處理這些相同的頭文件大大的增加了編譯的時(shí)間。

C++Builder是如何通過(guò)預(yù)編譯頭文件的方法來(lái)減少編譯時(shí)間的
  Borland的工程師熟悉到可以設(shè)計(jì)一個(gè)不用一遍又一遍處理同樣的頭文件的編譯器來(lái)減少編譯時(shí)間。于是Borland c++3.0中引入了預(yù)編譯頭文件的概念。處理方法很簡(jiǎn)單,當(dāng)編譯器處理源文件中的一組頭文件時(shí),把編譯好的映象文件保存在磁盤(pán)上,當(dāng)其它的源文件是引用同樣的一組頭文件時(shí)編譯器直接讀取編譯好的文件而不是再一次分析。
  修改一下剛才的控制臺(tái)程序來(lái)看看預(yù)編譯頭文件是如何減少編譯時(shí)間的。代碼本身不用修改,僅僅把工程選項(xiàng)中的預(yù)編譯頭文件選項(xiàng)再選中就行了。選擇Options-Project-Compiler并選中Use pre-compiled headers或是Cache pre-compiled headers。在預(yù)編譯頭文件名一欄中填入PCH.CSM。改好之后從重編譯工程。
  編譯過(guò)程中注重一下編譯進(jìn)度對(duì)話框。你會(huì)發(fā)現(xiàn)當(dāng)編譯器編譯project1.cpp時(shí)要處理130,000行代碼,而編譯UN99v1.cpp時(shí)只處理20行代碼。當(dāng)編譯器分析第一個(gè)源文件時(shí)產(chǎn)生了一個(gè)預(yù)見(jiàn)編譯頭文件的映象,在處理第二個(gè)文件時(shí)直接用來(lái)提高編譯速度。可以想象當(dāng)源文件的數(shù)目不是2而是50時(shí),性能會(huì)提高多少!



VCL GUI工程中預(yù)編譯頭文件的說(shuō)明
  通過(guò)預(yù)編譯頭文件的方法,上一個(gè)示例起碼減少了50%的編譯時(shí)間。而這不過(guò)僅僅是一個(gè)沒(méi)什么功能的簡(jiǎn)單的控制臺(tái)程序而已。你也會(huì)到在VCLGUI程序中會(huì)怎么樣呢?缺省情況下,c++builder自動(dòng)打開(kāi)工程的預(yù)編譯頭文件選項(xiàng)的。但它僅僅對(duì)vcl.h文件進(jìn)行預(yù)處理,這個(gè)頭文件可以在任何一個(gè)窗體的源文件頂端找到。

#include <vcl.h>
#pragma hdrstop
#pragma hdrstop指令通知編譯器停止產(chǎn)生預(yù)編譯映象。在hdrstop指令之前的#include語(yǔ)句會(huì)被預(yù)編譯,之后的就不會(huì)了。

  那當(dāng)vcl.h被預(yù)編譯時(shí)到底有多少頭文件也被預(yù)編譯了呢?可以查看一下vcl.h,看到它包含了另一個(gè)叫做vcl0.h的頭文件。假如你沒(méi)有更改C++builder的缺省設(shè)置,vcl0.h就包含了一小組vcl的頭文件,它們是:

// 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>

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 奈曼旗| 新巴尔虎右旗| 博罗县| 宣化县| 阿勒泰市| 山东省| 平乐县| 肇庆市| 新河县| 宁海县| 岗巴县| 蛟河市| 辽宁省| 红桥区| 凯里市| 平顶山市| 河曲县| 巴马| 清徐县| 大理市| 台东县| 依安县| 获嘉县| 五常市| 昭通市| 格尔木市| 贵德县| 郎溪县| 荣成市| 株洲市| 临沭县| 西平县| 维西| 施秉县| 宁化县| 浏阳市| 格尔木市| 拜泉县| 石台县| 东辽县| 泾源县|