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

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

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

四. 最佳化你的使用
通常最佳化都有幾個方面:更快的執行速度,有效的資源使用,更小的記憶體使用。一般情況下,程式碼最佳化都是試圖在以上各個方面進行改善。重新放置宣告技術被證明是消除多餘的建立和銷燬,這樣既減小了的大小又加快了執行速度。然而其他的最佳化技術都是基於一個方面------更快的速度或者是更小的記憶體使用。有時,這些目標是互斥的,了記憶體的使用往往卻減慢了程式碼速度,的程式碼卻又需要更多的記憶體支援。下面總結兩種在記憶體使用上的最佳化方法:
1. Bit Fields
在C/C++中都可以存取和訪問資料的最小組成單元:bit。因為bit並不是C/C++基本的存取單元,所以這裡是透過犧牲執行速度來減少記憶體和輔助器的空間的使用。注意:一些結構可能提供了特殊的指令來存取bit,因此bit fields是否影響程式的速度取決於具體平臺。
在我們的現實生活中,一個資料的許多位都被浪費了,因為某些應用根本就不會有那麼大的資料範圍。也許你會說,bit是如此之小,透過它就能減小儲存空間的使用嗎?的確,在資料量很小的情況下不會看出什麼效果,但是在資料量驚人的情況下,它所節省的空間還是能夠讓我們的眼睛為之一亮的。也許你又會說,現在記憶體和越來越便宜,何苦要費半天勁,這省不了幾個錢。但是還有另外一個原因一定會使你信服,那就是數字資訊傳輸。一個分散式都會在不同的地點有多份複製。那麼數百萬的紀錄傳輸就會顯得十分昂貴。Ok,現在我們就來看看該如何做吧,首先看下面這段程式碼:
struct BillingRec
{
  long cust_id;
  long timestamp;
  enum CallType
    {
     toll_free,
    local,
    regional,
    long_distance,
   international,
    cellular
  } type;
    enum CallTariff
  {
    off_peak,
    medium_rate,
    peak_time
  } tariff;
};
上面這個結構體在32位的機器上將會佔用16位元組,你會發現其中有許多位都被浪費了,尤其是那兩個enum型,浪費更是嚴重,所以請看下面做出的改進:
struct BillingRec
{
  int cust_id: 24; // 23 bits + 1 sign bit
  int  timestamp: 24;
  enum CallType
    {//...
    };
    enum CallTariff
      {//...
   };
   unsigned call: 3;
  unsigned tariff: 2;
};
現在一個資料從16位元組縮減到了8位元組,減少了一半,怎麼樣,效果還是顯著的吧:)
2. Unions
Unions透過把兩個或更多的資料成員放置在相同地址的記憶體中來減少記憶體浪費,這就要求在任何時間只能有一個資料成員有效。Union 可以有成員,包括建構函式和解構函式,但是它不能有虛擬函式。C++支援anonymous unions。anonymous union是一個未命名型別的未命名物件。例如:
union { long n; void * p};  // anonymous
n = 1000L;  // members are directly accessed
p = 0; // n is now also 0
不像命名的union,它不能有成員函式以及非public的資料成員。
那麼unions什麼時候是有用的呢?下面這個類從資料庫中獲取一個人的資訊。關鍵字既可以是一個特有的ID或者人名,但是二者卻不能同時有效:
class PersonalDetails
{
private:
  char * name;
  long ID;
  //...
public:
  PersonalDetails(const char *nm);  //key is of type char * used
  PersonalDetails(long id) : ID(id) {} //numeric key used 
};
上面這段程式碼中就會造成記憶體的浪費,因為在一個時間只能有一個關鍵字有效。anonymous union可以在這裡使用來減少記憶體的使用,例如:
class PersonalDetails
{
private:
  union  //anonymous
  {
    char * name;
    long ID;
  };
public:
  PersonalDetails(const char *nm);
  PersonalDetails(long id) : ID(id) {/**/}  // direct access to a member
  //...
};
透過使用union,PersonalDetails類的大小被減半。但是這裡要說明的是,節省4 個位元組記憶體並不值得引入union所帶來的麻煩,除非這個類作為數百萬資料庫記錄的型別或者紀錄在一條很慢的通訊線路傳輸。值得注意的是unions並不引入任何執行期負擔,所以這裡不會有什麼速度上的損失。anonymous union的優點就是它的成員可以被直接訪問。


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

相關文章