託管應用程序的性能實際上超過了非託管應用程序?

讀了《CLR via C#》後,知道了它的作者Jeffrey Richter。

真的是大神啊~

書中有一段話差點毀了我的世界觀,價值觀和愛情觀:

「雖然這樣說很難讓人信服,但許多人(包括我)都認為託管應用程序的性能實際上超過了非託管應用程序。有許多原因使我們對此深信不疑---例如,當JIT編譯器在運行時將IL代碼編譯成本地代碼時,編譯器對執行環境的認識比非託管編譯器更深刻。」

「JIT編譯器能判斷代碼是否運行在一個Intel Pentium 4 CPU上,並生成相應的本地代碼來利用Pentium 4支持的任何【特殊】指令,相反,非託管代碼通常是針對通用的、具有最小功能集合的CPU編譯的,不會使用提升應用程序性能的特殊指令。」


這段話不完全正確,它是基於理想情況說的。而且沒有考慮如內存佔用優化之類的特殊hack。託管更像是一種理想化的「通用」,讓開發者專註於程序本身而不是針對各平台進行優化。理論上來說確實託管很棒,但是當具體到一些現實的、細緻的應用場景的時候,託管不一定是最好的選擇。

比如說.Net Native就可以大幅度提高許多應用的效能。這不是說託管不好,而是說.Net Native的運行方式更適合這種場景。比如說PC上運行的應用程序,用.Net Native就很好。而伺服器上運行的大型程序那麼可能還是託管更合適


有點道理。比如x86的內存操作來說,內存操作,如複製內存,清0內存等是很耗時的,x86一直有一個repmovsb指令,但是很不幸這個指令在以前的機器上還不如c用long來複制內存快。後來intel改進了這個指令,那麼在改進過的機器中,最快的就是用repmovsb完成的。但是發布的代碼不能直接使用,否則在沒有改進過的機器上就會性能大大降低。這樣的例子還有很多。

但是linux內核有一種動態修改的方式,在程序初始化的時候,會判斷機器是否支持新特性,然後修改下代碼。應用程序要這樣實現也可以的,就是麻煩點,或者說大部分應用不會去這麼做。


所以.Net Native完全沒必要搞么?嗯……


這個論點不是JR發明的。我記得在Java剛出來沒幾年,性能還相當糟糕的時候就有人認為,從理論上講,基於VM的程序在性能上遲早會超過本地程序。

可是Java虛擬機已經優化這麼多年了,優化手段也算是十八般武器都用上了吧,仍然沒有明確的證據可以證明託管程序比本地程序性能高。Android最新的優化方法是安裝時把託管程序編譯成本地程序。SQL Server安裝的時候明顯有一個NativeGen的階段。你說要是託管程序比本地程序性能高的話,寫程序的人是吃飽了撐的?


其實JR大牛的話,正確的理解方法是這樣的:

你們這群垃圾,寫出來的C++當然不如我們(代詞,JR不是微軟員工,他是vendor)寫的.net好啊,所以比不過GC有什麼可笑的。你要讓我來寫,我C++就寫得比帶GC的C#強。

我在讀書的時候也跟大眾有差不多的判斷,後來就被自己寫的C#程序的性能驚呆了。隨著我C++越來越牛逼,性能的差距已經逐漸縮短,現在在一些「專業」的地方,我的C++代碼跑起來已經比C#快了。深刻的印證了這個道理。

當然了我還有很多C++代碼跑的並沒有C#快,C#的GC還是比C++的new快太多了。

說到為什麼,GC在大部分情況下快是理所當然的啊,不然為什麼你們總要在C++裡面做內存池。不過你們的內存池跟C#的GC相比差距實在是太大了,所以就算你們寫了,大多數情況下還是更慢(逃


特定應用的話,甚至腳本比c快都不奇怪。比如處理字元串,v8的js就非常快。

這是因為現代的腳本引擎優化,已經是彙編級的,解析極快,重要的是解析完成之後,某些代碼塊就是機器碼在運行。而且js的極致優化,可以理解為各種大神級的奇淫巧計,通常的c程序員是達不到的。


大神的意思是機器比人可靠,對一般的攻城獅來說,CLR對託管代碼的管理基本上是無懈可擊的,人家就是一家人啊,我等菜逼用好非託管就很容易達到大師對託管的管理水平了。


託管應用程序在第一次執行某些代碼的時候速度會比較慢。因為那時JIT還沒生成機器碼。


那native exe程序為什麼不支持多平台代碼合n為1啊?缺點就是代碼大點。我很不理解。


這是一句正確但不太實際的話。

JIT使得某些需要長期運行的,並且是計算為主的代碼,在*理論*上可以更快。但是到現在為止也沒看見過有令人信服的證據。另一方面,編譯器也有針對具體cpu進行優化,並不是說生成的代碼一定會慢。

但是在其他方面,不管是調用JIT本身,還是各種庫函數,原生的程序都比使用JIT的程序快的多。

所以,結局就象我們日常看到的一樣,一般來說原生的程序還是會更快。


測試案例瘋狂的讓C/C++ 分配對象或調用未好好buff的io即可達到目標


herb sutter

Reader QA: When will better JITs save managed code?

託管代碼可以更快是真的,但是凡事都有tradeoff,只要你能接受。


我記得這是CSDN上的很老的帖子啊,虧得輪子哥還一本正經的回答了


只是C/Cxx編譯80386的指令集好了 在支持80686指令集上運行 納尼的 真浪費快給我編譯成80686 還要帶mmx>﹏<

變成80686指令集了 卻到了 80386的平台 cpu說 你媽 給的什麼指令集 老子看不懂了 給你瞎執行了。

C# 我要運行了 讓我看看 當前的平台支持啥 指令集 (? _ ?)

我靠 mmx可以用 好 這段代碼就用mmx的


我就搞不懂了大家為什麼上來就討論性能?既然你的應用程序要求性能了,不是應該上並行計算什麼的了么?語言提升的那點性能算個球?!


推薦閱讀:

如何學習C#編程?
有哪些原因會導致HRESULT:0x800704A6提示已經計劃系統關機,除了更新系統或瀏覽器?
如何看待 Unity 與 Xamarin 均僅支持 C# 而不支持 VB.NET?
entity framework中怎麼通過lambda表達式生成sql語句的?

TAG:C | C# | MicrosoftVisualStudio |