※ 引述《tinlans.bbs@whshs.cs.nccu.edu.tw (汀)》之銘言:
: ※ 引述《HZYSoft.bbs@ptt.cc (PCMan 2004)》之銘言:
: > 其實通常不一定是這麼回事,也未必有 overhead
: 是的,這種 size 上的 overhead 「未必」會發生,
: 然而目前大多數的編譯器在 class 本身狀況複雜時幾乎會有 overhead,
: 目前我手上沒有 MSVC 編譯器,
: 但依經驗和印象來說 MSVC 在多重和虛擬繼承的情形,
: 並無法避開 member function size overhead 的發生,
: 這可能需要請有 MSVC 編譯器的人實驗看看。
在實際使用上,很多時候並不會用到那麼多的多重和虛擬繼承,或者可以避開
像是 MFC, wxWidgets... 等,就沒什麼用到,當然那是因為歷史的因素
而且完全避開使用這些其實 C++ 就像是斷了一條腿....很可惜
: > 在 inline 的時候可以避免 overhead,且就算沒 inline 不見得比較慢
: 在使用 member function pointer 時,
: 和 function object(或稱 functor)的 operator() 可被 inline 情形不同,
: 由於無法確定會 bind 的對象,
: 只要有點複雜的程式就會造成無法 inline 的狀況,
: 幾乎沒有 inline 的可能性。
真是不好意思,昨天沒睡頭很昏,我在回文的時候記到別篇的內容去了
function 可以 inline,但取 pointer 時跟 inline 確實是沒什麼關係
: > 以下舉相當常用的 Visual C++ 為例
: > member function 和 一般的 static function 其 pointer 大小完全一樣
: 寫到這裡,我特地用 google 搜尋了一下,
: 您可以參考看看 http://www.codeproject.com/cpp/FastDelegate.asp,
: 裡面的 Implementations of Member Function Pointers 段落中有一張表,
: 若其內容為真,您可能要重新考慮一下如此肯定的說法是否有問題。
抱歉我沒有講清楚,這裡指的是最簡單的 member function,就是在沒有
多型或虛擬的時候。在這種狀況下確實是一樣,考慮虛擬又是另一回事 :)
這篇是好文章,我沒有拜讀過,先前也沒有學過任何和 compiler 相關的知識
相關的東西是反組譯 C++ 時觀察到的,感謝指正。
事實上就 asswmbly 的觀點來看,這些 function 和 pointer 真的沒多大差別
C++ 語法固然很多,執行時原理也都一樣,反組譯之後就沒這麼多差異了 :P
至於 size 的問題個人覺得實在不需要討論,在不同平台不同 compiler 都不一樣
一直要考慮這些的話,乾脆就不要用 C++ 了,討論純粹只是好玩。
: > 差別只在 calling convention,一個是 C 的 calling convention
: > 另一個是 this call,也就是 call 的時候把 this pointer 放入 ECX register
: > 其實這效果跟 fast call 相當類似,function pointer 本身和 static function 無異
: > void gtk_window_set_title(register GtkWindow* window, gchar* title);
: > void GtkWindow::set_title(gchar* title);
: > 上面兩行實際執行的效果和 overhead 基本上完全一樣,而早期的 C 不能 inline
: > 所以 C++ 有時不但不會比較慢,而且經常能略勝 C 一籌
: > 一般來說 Getter 和 Setter function 都會寫成 inline,無 overhead
: > C++ 的 function 會有 overhead 的地方主要在 virtual function,
: > 而非所有 member function 都會,事實上大多 member function 和 C 沒差
: > 以上雖然沒有明文規範,但是編譯器基本上不會選擇用比較有 overhead 的方式實做
: 這部分的爭議倒是比較不那麼大。
: > 這些東西教授不知道很正常,換一個好的演算法往往勝過你省下上千個 overhead
: > 研究演算法的人不需計較這種實做細節,那對他們沒有意義。
: 這牽涉到我第一篇回文的重心,您可能沒有注意到,
: 就是原發文者說在學校學不到東西,
: 而我列出一些原因告訴原發文者不應該期待學校會教什麼,
: 然後列出一些教授誤人子弟的言論。
原來如此,不好意思沒看先前的討論串
: 另外,通常教 C++ 語言這門課的教授不應該是專門做演算法的,
: 因為「程式語言」和「程式設計」這兩門課並不適合這類教授進行教學,
: 除非是年輕時代對 C++ 很有興趣之後才轉型走向演算法的老教授,
非常同意!
: 但依 C++ standard 制訂的年代來說,這種老教授應該不存在。
: 再來,會被此類 overhead 拖累的演算法一般來說不是偏重效能考量,
: 而是偏重空間使用考量,這也是近幾年來新興的論文題目之一,
: 由於記憶體容量越來越大,對 PC 以上等級的系統研究節省記憶體意義已經不大,
: 很多論文已經轉向記憶體受限環境下如何節省空間的使用,
: 譬如現在被台灣政府炒到翻的嵌入式系統與 SoC 設計裡的軟體部分,
: 這類 overhead 常在研究生要跑數據丟 paper 前才被注意到,
: 不少例子是為了畢業在論文數據上動手腳,
: 國外倒是會有老實招認然後投去 conference 的情形。
: 上面兩段是分別就教育面和學術研究價值面做探討,
: 最後這裡就是實務面的考量了,
: 一般來說 C++ 程式除了 OOP 外還注重一般化(也就是 generic),
: 為求避免發生「寫死」的情形,
: 聽信或教人「xxxxx 的 size 在 xxx 一定是 xxxx bytes」是很不好的,
: 我曾經看過有人製作 pointer 容器時,
: 使用一般 function pointer size 初始化每個元素的大小,
: 然後試圖將 member function pointer 和一般 function pointer 塞在一起,
: 這位仁兄後來的確用很奇怪的方式達到他的目的了,
: 不過很遺憾的是之後他拿去別的平台無法編譯他的程式。
有趣的是,印象中好像有些 compiler 會過
VC++ 6 最有趣,function pointer 還可以透過轉 int 強制塞入 data pointer
再奇怪的實作方法用 VC++ 6 幾乎都有辦法讓他編譯過... orz
問題是...在 Windows 平台上,好像沒見過多少 compiler 可以編譯出比 VC++ 6
還要小的執行檔... (hello world 不算) 他的 optimization 其實很厲害
: 至於為何要做 pointer 容器?印象中是為了實作 thread manager...
: 後來這位仁兄看到 C# 的問世以及 delegate 的到來,
: 快樂的棄 C++ 投向 C# 的懷抱當中...
: 又,如果希望能夠充分發揮 C++ 的所有威力而又毫無阻礙,
: 我個人建議是使用 Comeau C++,雖然它要錢(可是不貴),
: GCC 目前在 4.1 版重寫了 C++ parser,試圖將 template 的支援做得更好,
: GCC 至今仍然毫無計畫實現 export 的功能,
: MSVC 的狀況我不清楚,事實上我幾乎沒有用過 MSVC 寫過 C++ 程式。
MSVC 6 對標準相容性惡名昭彰,但是最佳化滿強的
MSVC .NET IDE 變得很難用,故意改成跟 VB 一樣,檔案變大速度也變慢了
同樣參數編譯出來的檔案也變大,速度有無變快不知道,
C++ 標準符合度據說可以接受,編譯速度似乎沒有 VC6 快? 忘記了
但改版過的 MFC 和 編譯出的 exe 確定都比 VC6 時代還要大
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.129.67.69