C#一定比C++性能差?當然不!破除迷信,從我做起!


幾乎所有的程序員在初學編程之時,都被灌輸過“托管語言(Java、C#)性能比非托管語言(C、C++)差好多” 的迷信教條。如果你問他們為什么,他們一定會說:托管語言需要通過虛擬機或JIT編譯器對中間語言進行解釋,會耗費更多的內存和CPU運算時間,而非托管語言則會被直接編譯成本地代碼,可以直接運行,省去了大量運算。

那么,事實真的是這個樣子嗎?當然不是!

持以上論調的程序員一般分兩類:一類是用C、C++起家的工程師,他們從來沒有用過托管語言,也沒有深入了解過相關原理,對托管語言的運行機制有一些誤解;還有一類是低級程序員,他們不了解程序編譯原理,讀不懂也不想讀相關的書籍,只是覺得非托管語言很難,會用非托管語言的一定是大神,大神說的肯定是對的。然而,其實很多C、C++工程師想轉Java、C# 並不比Java、C#工程師轉C、C++容易多少,因為兩類語言的編程思想完全不一樣,想要轉變是非常困難的。

言歸正傳,為什么我說托管語言的性能不一定比非托管語言低呢?

首先要承認, JIT編譯的確會耗費更多的運算時間(相對於本地代碼),但這不代表本地代碼一定比托管代碼性能更好。

中間代碼的確是需要JIT編譯器在運行時進行解釋,翻譯成本地代碼運行的,這也是很多人產生誤解的地方。中間代碼的存在是保證程序跨平台運行的核心機制,中間代碼可以使得開發人員不再關注自己使用的語言,也不再關注程序運行的目標平台,不論開發者使用VB.NET還是C#,不論程序是要運行在x86平台、x64平台、安騰平台或者ARM平台,不論程序是要運行在Windows XP、Windows 10 還是Linux,開發者都不需要修改自己的代碼,真正做到一次編寫,多平台運行。雖然C、C++也能實現,但是卻有很大的局限性,這個后面會說。

但是,中間代碼會造成性能下降嗎?會!但是完全可以忽略,甚至在某些時候JIT要比本地代碼性能更好。

一方面,微軟在JIT編譯器中做了多種優化,包括本地代碼的緩存機制、分支預測,對於客戶端程序,微軟還提供了NGen工具,可以將中間代碼一次性編譯成本地代碼;對於服務器程序,在第一次加載程序池時,JIT就已經把所有中間代碼解釋完成了。所以,如果說性能低,主要表現也就是程序的啟動速度會慢一丟丟,運行起來以后就幾乎沒有影響了。所以說這種影響是可以被忽略的。

但是,就算是客戶端應用,微軟也建議開發者要做性能測試,然后在判斷是否要在生產環境中使用NGen工具優化代碼。因為在絕大部分情況下,本地代碼的性能甚至要比中間代碼還要差!

這里就要簡單介紹一下JIT編譯器的優勢了。對於想C、C++這樣的語言,會被編譯器直接編譯成機器語言,但是由於運行環境不確定,特別是CPU指令的差異。這些差異在編譯時都要考慮進去才能保證兼容性。而JIT編譯器則可以根據程序所在的平台,使用不同的解釋方案,能夠最大程度的利用平台的優秀特性,對性能會有很大的提升。

在Jeffery Richter所著的《CLR via C#》中,對JIT的運行原理有詳細的敘述,以下是一些摘要:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM