幾乎全部的程序員在初學編程之時,都被灌輸過「託管語言(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編譯器則能夠根據程序所在的平臺,使用不一樣的解釋方案,可以最大程度的利用平臺的優秀特性,對性能會有很大的提高。blog
在Jeffery Richter所著的《CLR via C#》中,對JIT的運行原理有詳細的敘述,如下是一些摘要: