JIT與靜態(tài)編譯器
如前所述,JIT可以在運(yùn)行時(shí)將IL/字節(jié)碼編譯成本機(jī)代碼。報(bào)告提到了這方面的成本,但沒有得出結(jié)論:
JIT有一個(gè)巨大的問題:它不能編譯所有的東西:JIT編譯需要時(shí)間,所以JIT只會(huì)編譯代碼的某些部分,而靜態(tài)編譯器將生成一個(gè)完整的本機(jī)二進(jìn)制:對(duì)于某些類型的程序,靜態(tài)編譯器只會(huì)輕松地超過(guò)JIT。
當(dāng)然,C#(或Java,或VB)通常比C+更快地產(chǎn)生可行和健壯的解決方案(如果僅僅因?yàn)镃+具有復(fù)雜的語(yǔ)義,而C+標(biāo)準(zhǔn)庫(kù)雖然有趣且功能強(qiáng)大,但與.NET或Java的標(biāo)準(zhǔn)庫(kù)的全部范圍相比,它很差),所以通常,C+與.NET或JavaJIT之間的區(qū)別對(duì)大多數(shù)用戶來(lái)說(shuō)是不可見的,對(duì)于那些至關(guān)重要的二進(jìn)制文件,好吧,您仍然可以從C#或Java調(diào)用C+處理(即使這種本地調(diào)用本身成本很高).
C+元編程
請(qǐng)注意,通常,您將C+運(yùn)行時(shí)代碼與其在C#或Java中的等效代碼進(jìn)行比較。但是C+有一個(gè)可以優(yōu)于Java/C#的特性,那就是模板元編程:代碼處理將在編譯時(shí)完成(從而大大增加編譯時(shí)間),從而導(dǎo)致運(yùn)行時(shí)為零(或幾乎為零)。
我還看到了現(xiàn)實(shí)生活對(duì)此的影響(我只玩了一些概念,但到那時(shí),JIT的執(zhí)行時(shí)間是幾秒了,而且零(對(duì)于C+),但是值得一提的是,除了模板元編程之外,.
編輯2011-06-10:在C+中,處理類型是在編譯時(shí)完成的,這意味著生成調(diào)用非泛型代碼的泛型代碼(例如,從字符串到T類型的泛型解析器,為它識(shí)別的類型調(diào)用標(biāo)準(zhǔn)庫(kù)API,并使解析器易于被其用戶擴(kuò)展)是非常容易和非常有效的,而Java或C#中的等價(jià)物編寫起來(lái)最好是痛苦的,而且即使在編譯時(shí)知道類型時(shí),也總是比較慢和解析。希望就是讓JIT把整件事都做好。
...
編輯2011-09-20:閃電戰(zhàn)+(首頁(yè), 維基百科),顯然,他們的目標(biāo)是通過(guò)C+模板元編程,盡可能從運(yùn)行時(shí)執(zhí)行轉(zhuǎn)移到編譯時(shí)間,從而達(dá)到FORTRAN在科學(xué)計(jì)算方面的性能。所以“我還沒有看到現(xiàn)實(shí)生活對(duì)這件事的影響。“顯然,我上面寫的部分是嗎?存在于現(xiàn)實(shí)生活中。
本機(jī)C+內(nèi)存使用
C+的內(nèi)存使用量不同于Java/C#,因此具有不同的優(yōu)點(diǎn)/缺陷。
無(wú)論進(jìn)行JIT優(yōu)化,沒有什么比直接訪問內(nèi)存的指針更快了(讓我們暫時(shí)忽略處理器緩存等等)。因此,如果內(nèi)存中有連續(xù)的數(shù)據(jù),可以通過(guò)C+指針(即C指針.讓我們給凱撒應(yīng)得的回報(bào)吧)將會(huì)比Java/C#快一倍。C+有Raii,這使得處理過(guò)程比C#甚至Java容易得多。C+不需要using
以確定其對(duì)象的存在范圍。而C+沒有finally
條款。這不是錯(cuò)誤。
:-)
盡管C#原語(yǔ)類結(jié)構(gòu),C+“在堆棧上”對(duì)象在分配和銷毀時(shí)不會(huì)花費(fèi)任何費(fèi)用,并且不需要GC在一個(gè)獨(dú)立的線程中進(jìn)行清理。
至于內(nèi)存碎片,2008年的內(nèi)存分配器不是1980年以來(lái)的舊內(nèi)存分配器,它們通常與GC:C+分配相比不能在內(nèi)存中移動(dòng),是這樣的,但是,就像在Linux文件系統(tǒng)上那樣:當(dāng)碎片不發(fā)生時(shí),誰(shuí)需要硬盤碎片整理呢?為正確的任務(wù)使用正確的分配器應(yīng)該是C+Developer工具包的一部分?,F(xiàn)在,編寫分配器并不容易,然后,我們大多數(shù)人都有更好的事情要做,而且對(duì)于大多數(shù)使用來(lái)說(shuō),Raii或GC已經(jīng)足夠好了。
編輯2011-10-04:有關(guān)高效分配程序的示例:在Windows平臺(tái)上,因?yàn)閂ista,低碎裂堆默認(rèn)情況下啟用。對(duì)于以前的版本,可以通過(guò)調(diào)用winapi函數(shù)來(lái)激活lfh。堆信息)。在其他操作系統(tǒng)上,還提供了可供選擇的分配器(請(qǐng)參閱https:/secure.wikimedia.org/Wikipedia/en/wiki/malloc清單)
現(xiàn)在,隨著多核和多線程技術(shù)的興起,內(nèi)存模型變得更加復(fù)雜。在這個(gè)領(lǐng)域,我猜.NET有優(yōu)勢(shì),而且我被告知Java占據(jù)了優(yōu)勢(shì)。對(duì)于一些“光禿禿的金屬”黑客來(lái)說(shuō),贊美他的“接近機(jī)器”的代碼是很容易的。但是現(xiàn)在,手工生成更好的程序集要比讓編譯器完成任務(wù)要困難得多。對(duì)于C+來(lái)說(shuō),自十年來(lái)編譯器通常比黑客做得更好。對(duì)于C#和Java來(lái)說(shuō),這甚至更容易。
然而,新的標(biāo)準(zhǔn)C+0x將向C+編譯器強(qiáng)加一個(gè)簡(jiǎn)單的內(nèi)存模型,這將使C+中有效的多處理/并行/線程代碼標(biāo)準(zhǔn)化(從而簡(jiǎn)化),并使編譯器的優(yōu)化更容易、更安全。但是,在幾年后,我們將看到它的承諾是否屬實(shí)。
C+/CLI與C#/VB.NET
注意:在本節(jié)中,我討論的是C+/CLI,即.NET托管的C+,而不是本機(jī)C+。
上周,我接受了.NET優(yōu)化方面的培訓(xùn),發(fā)現(xiàn)靜態(tài)編譯器無(wú)論如何都是非常重要的。比JIT更重要。
在C+/CLI中編譯的相同代碼(或其祖先,托管C+)可能比C#(或VB.NET中的編譯器生成的IL與C#相同)中生成的相同代碼快一倍。
因?yàn)镃+靜態(tài)編譯器比C#生成已經(jīng)優(yōu)化的代碼要好得多。
例如,.NET中的函數(shù)內(nèi)聯(lián)僅限于字節(jié)長(zhǎng)度小于或等于32個(gè)字節(jié)的函數(shù)。因此,C#中的一些代碼將生成一個(gè)40字節(jié)訪問器,JIT不會(huì)將其內(nèi)聯(lián)。C+/CLI中的相同代碼將生成一個(gè)20字節(jié)訪問器,它將由JIT內(nèi)聯(lián)。
另一個(gè)例子是臨時(shí)變量,這些變量是由C+編譯器編譯掉的,而C#編譯器生成的IL中仍然提到這些變量。C+靜態(tài)編譯優(yōu)化將導(dǎo)致代碼減少,因此再次授權(quán)進(jìn)行更積極的JIT優(yōu)化。
之所以出現(xiàn)這種情況,是因?yàn)镃+/CLI編譯器從C+本機(jī)編譯器的大量?jī)?yōu)化技術(shù)中獲益。
結(jié)語(yǔ)
我喜歡C+。
但據(jù)我所見,C#或Java都是更好的選擇。這并不是因?yàn)樗鼈儽菴+更快,而是因?yàn)楫?dāng)你把它們的質(zhì)量加起來(lái)時(shí),它們最終會(huì)變得更有效率,需要更少的培訓(xùn),并且比C+擁有更完整的標(biāo)準(zhǔn)庫(kù)。對(duì)于大多數(shù)程序來(lái)說(shuō),它們的速度差異(在某種程度上)是可以忽略不計(jì)的.
編輯(2011-06-06)
我在C#/.NET方面的經(jīng)驗(yàn)
我現(xiàn)在幾乎有5個(gè)月的專業(yè)C#編碼(這意味著我的簡(jiǎn)歷中已經(jīng)滿是C+和Java,還有一點(diǎn)C+/CLI)。
我和WinForms一起玩(嗯.)和WCF(酷!)和WPF(酷!通過(guò)XAML和原始C#。WPF是如此簡(jiǎn)單,我相信Swing無(wú)法與之相比),和C#4.0。
結(jié)論是,雖然生成在C#/Java中工作的代碼比在C+中更容易/更快,但在C#中生成一個(gè)強(qiáng)大、安全和健壯的代碼要比在C+中生成一個(gè)強(qiáng)大、安全和健壯的代碼要困難得多。理由很多,但可以概括如下:
泛型不如模板強(qiáng)大。 (嘗試編寫一個(gè)有效的泛型分析方法(從String到T),或者在C#中編寫一個(gè)有效的相等于Boost:詞法_CAST的方法來(lái)理解這個(gè)問題。)
Raii仍然是無(wú)與倫比的 (GC仍然可以泄漏(是的,我必須處理這個(gè)問題),并且只處理內(nèi)存。連C#using
并不是那么簡(jiǎn)單和強(qiáng)大,因?yàn)榫帉懻_的Dispose實(shí)現(xiàn)是很困難的。)
C#readonly
和爪哇final
沒有比C+更有用的了const
(在沒有大量工作的情況下,您不可能在C#中公開只讀的復(fù)雜數(shù)據(jù)(例如,節(jié)點(diǎn)樹),而這是C+的內(nèi)置特性。不可變數(shù)據(jù)是一個(gè)有趣的解決方案,但并不是所有的東西都是不可變的,所以到目前為止,它還不夠).
所以,C#仍然是一種愉快的語(yǔ)言,只要你想要一些有用的東西,但在你想要的時(shí)候,它是一種令人沮喪的語(yǔ)言永遠(yuǎn)安全起作用了。
Java甚至更令人沮喪,因?yàn)樗兄cC#相同的問題,還有更多的問題:缺少與C#相同的問題。using
關(guān)鍵字,我的一位非常熟練的同事花費(fèi)了太多的時(shí)間來(lái)確保其資源被正確釋放,而在C+中的等價(jià)物則很容易(使用析構(gòu)函數(shù)和智能指針)。
所以我想C#/Java的效率提高對(duì)大多數(shù)代碼來(lái)說(shuō)是可見的.。直到有一天你需要代碼盡可能的完美。那天你會(huì)知道痛苦的。(你不會(huì)相信我們的服務(wù)器和GUI應(yīng)用程序要求什么)。
關(guān)于服務(wù)器端Java和C+
我和服務(wù)器團(tuán)隊(duì)保持聯(lián)系(在回到GUI團(tuán)隊(duì)之前,我在他們中間工作了兩年),在大樓的另一邊,我學(xué)到了一些有趣的東西。
過(guò)去幾年的趨勢(shì)是,Java服務(wù)器應(yīng)用程序注定要取代舊的C+服務(wù)器應(yīng)用程序,因?yàn)镴ava有許多框架/工具,而且易于維護(hù)、部署等。
.直到低潛伏期的問題在過(guò)去的幾個(gè)月里長(zhǎng)出了丑陋的頭.然后,Java服務(wù)器應(yīng)用程序,無(wú)論我們熟練的Java團(tuán)隊(duì)試圖進(jìn)行的優(yōu)化,簡(jiǎn)單而干凈地輸?shù)袅伺c舊的,而不是真正優(yōu)化的C+服務(wù)器的競(jìng)爭(zhēng)。
目前,我們的決定是將Java服務(wù)器保留在性能仍然重要但不關(guān)心低延遲目標(biāo)的通用服務(wù)器上,并積極優(yōu)化已經(jīng)更快的C+服務(wù)器應(yīng)用程序,以滿足低延遲和超低延遲的需求。
結(jié)語(yǔ)
沒有什么比預(yù)期的簡(jiǎn)單。
Java和更多的C#是很酷的語(yǔ)言,擁有廣泛的標(biāo)準(zhǔn)庫(kù)和框架,您可以在那里快速編寫代碼,并且很快就會(huì)有結(jié)果。
但是,當(dāng)您需要原始功能、強(qiáng)大和系統(tǒng)的優(yōu)化、強(qiáng)大的編譯器支持、強(qiáng)大的語(yǔ)言特性和絕對(duì)安全時(shí),Java和C#使您很難贏得最后一個(gè)缺失但關(guān)鍵的質(zhì)量百分比,您需要保持在競(jìng)爭(zhēng)之上。
與C+相比,您需要更少的時(shí)間和更少經(jīng)驗(yàn)的C#/Java開發(fā)人員來(lái)生成平均質(zhì)量代碼,但另一方面,當(dāng)您需要優(yōu)秀的代碼來(lái)完善質(zhì)量代碼時(shí),在C+中得到正確的結(jié)果突然變得更容易和更快了。
當(dāng)然,這是我自己的看法,也許只限于我們的具體需要。
但是,這仍然是今天發(fā)生的事情,無(wú)論是GUI團(tuán)隊(duì)還是服務(wù)器端團(tuán)隊(duì)。
當(dāng)然,如果有新的事情發(fā)生,我會(huì)更新這篇文章。
編輯
“我們發(fā)現(xiàn),在性能方面,C+以很大的優(yōu)勢(shì)勝出,然而,它也需要最廣泛的調(diào)優(yōu)努力,其中許多是在一般程序員無(wú)法使用的復(fù)雜程度上完成的。
[.]Java版本可能是最簡(jiǎn)單的實(shí)現(xiàn),但最難分析性能。具體來(lái)說(shuō),垃圾收集的影響很復(fù)雜,很難調(diào)整。“
資料來(lái)源:
編輯
“Facebook上最流行的說(shuō)法是‘寫得很好的C+代碼運(yùn)行得很快,這突出了在優(yōu)化PHP和Java代碼方面付出的巨大努力。矛盾的是,C+代碼比其他語(yǔ)言更難編寫,但是高效的代碼(用C+編寫比用其他語(yǔ)言編寫)要容易得多。"
– 草本薩特在…/構(gòu)建/引用亞歷山大斯庫(kù)
資料來(lái)源: