C++程式碼最佳化方法總結(二) (轉)
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++程式碼最佳化方法總結(一) (轉)C++
- C++程式碼最佳化方法總結(四) (轉)C++
- C++程式碼最佳化方法總結(三) (轉)C++
- 關於C++程式碼最佳化的方法總結(轉)C++
- C++ 層次程式碼最佳化 (轉)C++
- c++程式碼優化總結C++優化
- 微課sql最佳化(17)、不改程式碼,最佳化SQL(1)-最佳化方法總結SQL
- MySQL修改密碼方法總結 (轉)MySql密碼
- Delphi程式碼最佳化 完結篇 (轉)
- Delphi程式碼最佳化(二) 整數篇 (轉)
- C\C++控制檯程式隱藏方法總結C++
- C程式最佳化之路(二) (轉)C程式
- c++/tcl程式設計總結C++程式設計
- Dotfuscator針對C#程式碼混淆方法總結C#
- MySQL資料庫中修改密碼方法總結(轉)MySql資料庫密碼
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構學習(C++)——樹(總結) (轉)資料結構C++
- 前端和React Native程式碼互轉總結前端React Native
- 清除浮動方法總結(轉)
- Nginx常見錯誤程式碼總結和分析方法Nginx
- 程式設計技巧整理:Java程式效能最佳化總結!程式設計Java
- 二叉樹遍歷方法總結二叉樹
- Delphi 程式碼最佳化——字串篇 (轉)字串
- 程式碼走查總結
- Oracle常用的轉儲方法總結Oracle
- RMAN 命令總結(二)--轉自網路
- C++:字串總結C++字串
- MySQL修改密碼方法總結YRMySql密碼
- duwamish7的一些程式碼分析總結 (轉)
- Prefer C++ (二) (轉)C++
- C++日期和時間程式設計總結C++程式設計
- C++ 多執行緒程式設計總結C++執行緒程式設計
- Oracle SQL最佳化總結OracleSQL
- 總結MYSQL的最佳化MySql
- borland c++ bulder的檔案操作總結-2 (轉)C++
- borland c++ bulder的檔案操作總結-1 (轉)C++
- borland c++ bulder的檔案操作總結-3 (轉)C++
- borland c++ bulder的檔案操作總結-4 (轉)C++