在我們的**中,有些臨時物件正在使用而我們並未察覺;
效能優化時,消除臨時物件,特別是大的臨時物件,對提公升效能效果明顯;
這裡列出常見的臨時物件產生的地方:
按值返回函式結果,結果就是乙個臨時物件
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無名則無份...