C++程式碼最佳化方法總結(二) (轉)

amyz發表於2007-11-16
C++程式碼最佳化方法總結(二) (轉)[@more@]

  C++程式碼方法總結(二)
  cpp  to:cpp_bug@.com">cpp_bug@hotmail.com

三. 內聯
行內函數既能夠去除函式所帶來的負擔又能夠保留一般函式的優點。然而,行內函數並不是萬能藥,在一些情況下,它甚至能夠降低的。因此在使用的時候應該慎重。
  1.我們先來看看行內函數給我們帶來的好處:從一個的角度來看,行內函數看起來和普通函式一樣,它可以有引數和返回值,也可以有自己的作用域,然而它卻不會引入一般函式呼叫所帶來的負擔。另外,它可以比宏更更容易。
 當然有一點應該意識到,inline specifier僅僅是對的建議,編譯器有權利忽略這個建議。那麼編譯器是如何決定函式內聯與否呢?一般情況下關鍵性因素包括函式體的大小,是否有區域性被宣告,函式的複雜性等等。
  2.那麼如果一個函式被宣告為inline但是卻沒有被內聯將會發生什麼呢?理論上,當編譯器拒絕內聯一個函式的時候,那個函式會像普通函式一樣被對待,但是還會出現一些其他的問題。例如下面這段程式碼:
  // filename Time.h
#include
#include
using namespace std;
class Time
{
public:
   inline void Show() { for (int i = 0; i<10; i++) cout<

// filename f2.cpp
#include "Time.h"
void f2()
{
  Time t2;
  t2.Show();
}
結果編譯器為這個程式生成了兩個相同成員函式的複製:
void f1();
void f2();
int main()
{
  f1();
  f2();
  return 0;
}
當程式被連結的時候,linker將會面對兩個相同的Time::Show()複製,於是函式重定義的連線錯誤發生。但是老一些的C++實現對付這種情況的辦法是透過把一個un-inlined函式當作static來處理。因此每一份函式複製僅僅在自己的編譯單元中可見,這樣連結錯誤就解決了,但是在程式中卻會留下多份函式複製。在這種情況下,程式的效能不但沒有提升,反而增加了編譯和連結時間以及最終可體的大小。
但是幸運的是,新的C++標準中關於un-inlined函式的說法已經改變。一個符合標準C++實現應該只生成一份函式複製。然而,要想所有的編譯器都支援這一點可能還需要很長時間。
另外關於行內函數還有兩個更令人頭疼的問題。第一個問題是該如何進行維護。一個函式開始的時候可能以內聯的形式出現,但是隨著的擴充套件,函式體可能要求新增額外的功能,結果行內函數就變得不太可能,因此需要把inline specifier去除以及把函式體放到一個單獨的原始檔中。另一個問題是當行內函數被應用在程式碼庫的時候產生。當行內函數改變的時候,使用者必須重新編譯他們的程式碼以反映這種改變。然而對於一個非行內函數,使用者僅僅需要重新連結就可以了。
這裡想要說的是,行內函數並不是一個增強效能的靈丹妙藥。只有當函式非常短小的時候它才能得到我們想要的效果,但是如果函式並不是很短而且在很多地方都被呼叫的話,那麼將會使得可執行體的體積增大。最令人煩惱的還是當編譯器拒絕內聯的時候。在老的實現中,結果很不盡人意,雖然在新的實現中有很大的改善,但是仍然還是不那麼完善的。一些編譯器能夠足夠的聰明來指出哪些函式可以內聯哪些不能,但是,大多數編譯器就不那麼聰明瞭,因此這就需要我們的來判斷。如果行內函數不能增強行能,就避免使用它!

 



 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-982608/,如需轉載,請註明出處,否則將追究法律責任。

相關文章