消除臨時物件

2021-09-08 11:13:29 字數 1733 閱讀 6640

在我們的**中,有些臨時物件正在使用而我們並未察覺;

效能優化時,消除臨時物件,特別是大的臨時物件,對提公升效能效果明顯;

這裡列出常見的臨時物件產生的地方:

按值返回函式結果,結果就是乙個臨時物件

string add(string s1,string s2)

解決方案:

在大多數場景下,這個臨時物件可以通過按引用返回來消除;

void add(string s1,string s2,string& retvalue )

幸運的是,編譯器通常會對按值返回做優化,將其改寫為按引用返回;

但編譯器做的也是非常保守的工作,僅對匿名返回臨時物件做這種按引用傳遞;

以上函式就不會做,而以下函式,編譯器會自動優化為按引用傳遞:

string add(string s1,string s2)

注:返回值優化(rvo: return value optimition):由編譯器來完成將值返回轉換為引用返回;

按值傳遞引數,會有臨時物件的分配

string add(string s1,string s2)

解決方案:

改為按引用傳遞(如果不希望函式內部修改,加上const修飾符)

string add(const string& s1, const string& s2)

賦值操作兩邊不是同一型別時,如果右邊可以作為作為的建構函式的引數做隱式轉換,那麼就會有臨時物件的產生;

比如:

string s1;

s1 = "a";

首先會產生乙個臨時物件string:string("a");

然後賦值給s1: s1 = string("a");

解決方案:

盡量使用相同型別,不用編譯器來自動做隱式轉換:

比如:

初始化:

string s1("a");
賦值:

string s1;

s1.assign("a");

例:

string s3;

s3 = s1+ s2;

s1+s2的中間結果需要存到乙個臨時物件中,然後再賦值給s3;

解決方案:

採用+=操作符,乙個個的加上需要的物件:

s3 = s1; 

s3+= s2;

當然,第一種寫法更為優雅,第二種則效能高效;

當此處不是優化關鍵 路徑上的時候,我們還是採用第一種寫法就好;

class myclass

private:

string m_a;

}

成員物件放在建構函式中初始化,那麼必然產生乙個中間的臨時物件;

解決方案:

採用成員初始化列表:

class myclass

private:

string m_a;

}

posted by: 大cc | 06aug,2015

部落格:blog.me115.com [訂閱]

github:大cc

消除臨時物件

在我們的 中,有些臨時物件正在使用而我們並未察覺 效能優化時,消除臨時物件,特別是大的臨時物件,對提公升效能效果明顯 這裡列出常見的臨時物件產生的地方 按值返回函式結果,結果就是乙個臨時物件 string add string s1,string s2 解決方案 在大多數場景下,這個臨時物件可以通過...

消除mysql內部臨時表

在一些sql請求中,mysql會建立臨時表,可能建立到記憶體中,也可能由記憶體轉存到磁碟。會建立臨時表的查詢 1.group by的列沒有索引,必建立臨時表 2.order by與group by 為不同列時,或多表查詢時order by,group by 包含的列不是第一張表的列,必產生臨時表。3...

匿名物件?臨時物件?

關於匿名物件與臨時物件,這個概念不是絕對的,概念的區分往往十分拗口難記。要根據作用域,生存時間和用法來來決定 工作多年這些拗口的概念我從來沒有真的記住過,也沒有乙個部落格講清楚他們的區別。這裡我們參考 effective c 中得稱謂,稱之為區域性物件。但是區域性也是有範圍得。下面論證。1無名則無份...