關於近期C#大論戰的回應

來源:互聯網
上載者:User

 

自從在cnblogs和csdn寫了幾篇批評C#/.NET的博文後,便受到了多方.NET粉絲的輪番群毆:http://www.cnblogs.com/topic/53/。這段時間正好出差,沒有及時回複,便被部分朋友視作理屈詞窮。其實,我在第一篇博文中就說過,我既然列出這些論點,一定有支援這些論點的實踐證據和技術原因——也許有些觀點錯誤,但是我總有我的道理。說出來,和大家分享討論而已——沒有及時回帖,只是工作原因,絕不會理屈詞窮,請大家放心,我還會繼續戰鬥下去,呵呵:)

 

我仔細看了目前為止參與“群毆”的博文,說實話,大部分都是沒有技術含量、錯誤百出的。比如如下觀點:《說透 事件和介面,兩者怎能互相替代》:http://www.cnblogs.com/waitrabbit/archive/2010/07/02/1769948.html 博文中直接說“事件是特殊的委託”? 就這水平,還能“說透?”。先搞清楚什麼叫“委託”,什麼叫“介面”,什麼叫“事件”吧! 再比如:《完全水文系列之0xFA:函數背後的臃腫設計哲學》:http://www.cnblogs.com/winter-cn/archive/2010/07/05/1771098.html果然是水的厲害,自己都承認水了。我就不回應了。

 

不過,可喜的是,在眾多水貼之中,確實還出來了幾篇高品質的文章,這是讓我非常高興的,也算是對我寫系列博文的一個回報吧。目前看到的主要有以下幾個文章我列舉如下,並且加上我的回應(如果有朋友認為自己的文章品質很高,技術水平很深,我遺漏掉了,請在下面回帖,我會認真拜讀並回應),與大家一起討論、共勉:


1.  李建忠《Metadata是.NET平台的核心靈魂》:http://techvery.com/jzli/2010/07/07/metadata是-net平台的核心靈魂/

 

這篇博文是目前我看到技術分析最深入的一篇博文,讓我很受益。李建忠是我尊敬的一位.NET技術專家,我承認學習.NET就是從拜讀李建忠翻譯的《.NET架構程式設計》(Jeffrey Richter著,後改名為CLR via C#)一書開始,我也參加過李先生公司去年舉辦的.NET技術大會,才有前文提到的和Jeffrey Richter大牛的對話。

 

李建忠在這篇博文中批判了我之前博文中的一個論據“.NET平台中metadata的目的是為了支援反射”。我必須坦白地承認,我之前確實一直認為“metadata就是為了支援反射才建立的。” 經過李建忠博文的分析,我承認在這個問題上認識不到位,觀點偏頗。並且非常同意李建忠博文的觀點“.NET使用metadata的主要目的是實現組件的高度複用性”。

 

李建忠博文中還有很多很有價值的技術分析,比如COM的缺點,.NET為什麼使用metadata?metadata都在.NET中有哪些具體的應用?特別是“基於邏輯語義的組件複用”和“基於物理實現細節的組件複用”的對比,受益匪淺。

 

拜讀過這篇文章之後,我也承認“基於邏輯語義的組件複用”對於軟體開發平台非常重要,不過卻有一點要和李建忠商榷,難道“效能就不重要了嗎?”,“.NET為了基於邏輯語義的組件複用,就可以大幅度地犧牲軟體的效能嗎?”,非常希望聽到李建忠和網友的繼續分析。

 

 2. mikelij《關於.net反射和metadata載入--致Jeffray Zhao等幾位和firelong:http://www.cnblogs.com/mikelij/archive/2010/07/04/1770897.html

 

mikelij這篇博文涉及到兩個觀點:

a. 我在前面分析反射時的觀點:程式(EXE/DLL)最後都是要載入到記憶體中啟動並執行,不是光放在硬碟上的——這也是為什麼.NET程式佔用記憶體都超多。

b. Jeffray Zhao在前文中反駁我的觀點是 "不JIT的話,是不會把整個dll載入到記憶體中的,而是用多少載入多少,這點已經討論了很多遍了"

 

mikelij這篇博文非常細緻的分析和資料說理,以及其後面的網友跟帖討論已經清楚表明了,我在這個問題上的觀點是正確的。不過後面有很多跟帖一直在說“工作管理員裡面的記憶體佔用很小,所以說明老趙的觀點是正確的,即調用哪個方法,就載入哪個方法和它的中繼資料。用不到的方法,不載入”。

 

這個裡面觸及到了一個較深入的話題,即Windows作業系統的記憶體載入規則和Windows工作管理員的數字含義。 我對這個問題的回應如下:

 

Windows工作管理員顯示的記憶體大小指的是“工作集working set所使用的記憶體大小”,也就是當前運行期載入到CPU緩衝裡面的記憶體大小。並不是程式運行期間所有載入到記憶體中的資料。這些資料有可能停留在主存,或者虛擬記憶體即硬碟上——這就是效能成本,因為這很快會因為調用而遇到page fault, cache missing的問題。只是因為它們當前不被調用,所以沒有放在working set緩衝中,但是並不表明它們不被載入到主存或者虛擬記憶體中。

 

而程式在運行期間,EXE/DLL整個程式集是整體被載入,而不是部分載入——不會因為你只用一個程式集中的方法A,就只載入方法A。而是會將程式集中其他類、方法、中繼資料都載入進去:mikelij這篇博文充分證明了這一點。

 

JIT編譯是按照方法為單位——即用哪個方法,編譯哪個方法。但是載入是按照程式集為單位,不是以方法為單位——老趙在這個問題上的認識讓人失望。

 

謝謝mikelij這篇資料翔實的博文!


3. 老趙《我支援託管運行時(虛擬機器):http://blog.zhaojie.me/2010/07/why-i-support-managed-runtime-virtual-machine-based-program.html

 

實話實話老趙對.NET的很多分析還是有益的,至少讓我可以深入再思考一些問題,雖然老趙經常犯一些幼稚的錯誤(比如前面的將程式集的載入問題,混淆成了JIT問題)。 這篇文章中,老趙說了好幾個虛擬機器的優點,我整體比較同意,比如實現跨語言,“跨執行環境”等。

 

但是說虛擬機器完全可以實現比native代碼更高的效能,則有點過於他信.NET了。特別是舉出了一個虛函數的內聯最佳化的天方夜譚的神話,一個虛函數即便迴圈調用,你也絕對無法去預先判斷下一次的調用地址——如果可以判斷,這個判斷的成本,要遠遠高於內聯所節省的效能成本(而且是每一次都要判斷!)。老趙這個真的實現了嗎?能不能給出參考地址?

 

虛擬機器可以實現的最佳化,native代碼都可以,而且最佳化力度要大得多。但是很多native可以做的最佳化,虛擬機器就不行。虛擬機器,顧名思義要經過一層間接,我無論如何都想象不出來,間接層可以提升效能?希望老趙能夠深入分析一下原理或者給出案例。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.