條款30:透徹瞭解inlining的裏裏外外

條款30:透徹瞭解inlining的裏裏外外
    (Understand the ins and outs of inlining.)

內容:
    對於該款的描述,原文中用了6頁的篇幅進行闡述,這裏我就將重要的知識點羅列出來,方便大家更好的理解
這一條款.
    (1)inline函數的優缺點.
    優點:對於一個inline函數,你可以調用它們又不蒙受函數調用招致的額外開銷,編譯器就會對函數本體執行
語境相關最優化,而大部分編譯器不會對着一個非inline函數調用動作執行如此之最優化.
    缺點:由於對inline函數的每一個調用都以函數本體替換之,所以說這樣就可能增加你的目標代碼,在一臺有
限的機器上,過度熱衷inlining會造成程序體積太大,即使擁有虛擬內存,inline造成的代碼膨脹亦會導致額外的
換頁行爲,降低指令高速緩存裝置的擊中率,以及伴隨而來的效率損失.
    (2)inline只是對編譯器的一個申請不是強制命令,該申請可以隱喻提出也可明確提出,隱喻提出就是將函數
定義於class定義式內,這樣的函數通常是成員函數或者是friend函數.明確聲明就是在函數之前加關鍵字"inline".
    (3)inline函數通常一定要被置於頭文件內,其在大多數C++程序中是編譯器行爲.
    (4)大部分編譯器拒絕將太過複雜的函數inlining,而所有的virtual函數都不能inlining,因爲virtual意味
着"等待,知道運行期才確定調用哪個函數",而inline意味"執行前先將動作替換爲被調用函數的本體".
如果編譯器不知道該調用哪個函數,你就很難責備它們拒絕將函數本體inlining.
    (5)有時候編譯器inline某個函數的同時,還可能爲其生成一個函數本體(比如程序要取某個line函數地址),
值得一提的是,編譯器通常不對"通過函數指針而進行的調用"實施inling,這就是說line函數的調用可能是
被inlined,也可能不被inlined,取決於調用的實施方式.
    (6)"將構造函數和析構函數進行inling"是一個很糟糕的想法.看下面這段代碼:
    class Base{
    public:
        ...
    private:
        std::string bm1,bm2;
    };
    class Derived:public Base{
    public:
        Derived(){} //空函數耶,夠簡單了吧?我想讓它inlining,可以麼?
        ...
    private:
        std::string dm1,dm2,dm3;
    };
    這個構造函數看起來很簡單,inlining它應該沒問題嘛,呵呵,但你的眼睛可能會欺騙你.我們來看它的等價
代碼:
    Derived::Derived(){ //"空白Derived構造函數"的觀念性實現
        Base::Base();//初始化"Base成分"
       
        try{
            dm1.std::string::string();
        }catch(...){
            Base::~Base();
            throw;
        }
       
        try{
            dm2.std::string::string();
        }catch(...){
            dm1.std::string::~string();
            Base::~Base();
            throw;
        }
       
        try{
            dm3.std::string::string();
        }catch(...){
            dm2.std::string::~string();
            dm1.std::string::~string();
            Base::~Base();
            throw;
        }
    }
    這段代碼並不能代表編譯器真正製造出來的代碼,因爲真正的編譯器會以更精緻複雜的做法來處理異常.
儘管如此,這已能準確反映Derived的空白構造函數必須提供的行爲.
    (7)程序庫設計者必須評估"將函數聲明爲inline"的衝擊:inline函數無法隨着程序庫的升級而升級.
    我認爲的該款的重點都羅列出來了,如果有什麼不明白的地方,請留言.
    請記住:
    ■ 將大多數inlining限制在小型,被頻繁調用的函數身上.這可使日後的調試過程和二進制升級更容易,
也可使潛在的代碼膨脹問題最小化,使程序的速度提升機會最大化.
    ■ 不要因爲function templates出現在頭文件,就將它們聲明爲inline.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章