Java 與 C/C++ 的編譯器對比

前言

這兩天重溫了周志明的《深入理解Java虛擬機(jī)》第2版鸳粉,發(fā)現(xiàn)第11章第4節(jié)關(guān)于 Java 編譯器的內(nèi)容寫得太棒了~本文完全摘自《深入理解Java虛擬機(jī)》第2版 0_o

Java 與 C/C++ 編譯器

大多數(shù)程序員都認(rèn)為C/C++會比Java語言快绽媒,甚至覺得從Java語言誕生以來“執(zhí)行速度緩慢”的帽子就應(yīng)當(dāng)扣在它的頭頂李请,這種觀點(diǎn)的出現(xiàn)是由于Java剛出現(xiàn)的時候即時編譯技術(shù)還不成熟,主要靠解釋器執(zhí)行的Java語言性能確實比較低下。但目前即時編譯技術(shù)已經(jīng)十分成熟,Java語言有可能在速度上與C/C++一爭高下嗎绝编?要想知道這個問題的答案,讓我們從兩者的編譯器談起。

Java與C/C++的編譯器對比十饥,實際上代表了最經(jīng)典的即時編譯器靜態(tài)編譯器的對比窟勃,很大程度上也決定了Java與C/C++的性能對比結(jié)果,因為無論是C/C++還是Java代碼逗堵,最終編譯之后被機(jī)器執(zhí)行的都是本地機(jī)器碼秉氧,哪種語言的性能更高,除了它們自身的API庫實現(xiàn)地好壞之外蜒秤,其余的比較就成了一場拼編譯器的游戲汁咏。當(dāng)然,這種比較也是剔除了開發(fā)效率的片面對比作媚,語言孰優(yōu)孰劣攘滩、誰快誰慢的問題都是很難有結(jié)果的爭論,下面我們就回到正題掂骏,看看這兩種語言的編譯器各有何優(yōu)勢轰驳。

Java 編譯器“劣勢”的原因

Java虛擬機(jī)的即時編譯器與C/C++的靜態(tài)優(yōu)化編譯器相比厚掷,可能會由于下列原因霍掺,而導(dǎo)致輸出的本地代碼有一些劣勢(下面列舉的也包括一些虛擬機(jī)執(zhí)行子系統(tǒng)的性能劣勢):

第一逃魄,因為即時編譯器運(yùn)行占用的是用戶程序的運(yùn)行時間,具有很大的時間壓力,它能提供的優(yōu)化手段也嚴(yán)重受制于編譯成本拉讯。如果編譯速度達(dá)不到要求,那用戶將在啟動程序或程序的某部分察覺到重大延遲挪圾,這點(diǎn)使得即時編譯器不敢隨便引入大規(guī)模的優(yōu)化技術(shù)潘靖,而編譯的時間成本在靜態(tài)優(yōu)化編譯器中并不是主要的關(guān)注點(diǎn)。

第二冬竟,Java語言是動態(tài)的類型安全語言欧穴,這就意味著需要由虛擬機(jī)來確保程序不會違反語言語義或訪問非結(jié)構(gòu)化內(nèi)存。從實現(xiàn)層面上看泵殴,這就意味著虛擬機(jī)必須頻繁地進(jìn)行動態(tài)檢查涮帘,如實例方法訪問時檢查空指針、數(shù)組元素訪問時檢查上下界范圍笑诅、類型轉(zhuǎn)換時檢查繼承關(guān)系等调缨。對于這類程序代碼沒有明確寫出的檢查行為,盡管編譯器會努力進(jìn)行優(yōu)化吆你,但是總體上仍然要消耗不少的運(yùn)行時間弦叶。

第三,Java語言中雖然沒有virtual關(guān)鍵字妇多,但是使用虛方法的頻率卻遠(yuǎn)遠(yuǎn)大于C/C++語言伤哺,這意味著運(yùn)行時對方法接收者進(jìn)行多態(tài)選擇的頻率要遠(yuǎn)遠(yuǎn)大于C/C++語言,也意味著即時編譯器在進(jìn)行一些優(yōu)化(如方法內(nèi)聯(lián))時的難度要遠(yuǎn)遠(yuǎn)大于C/C++的靜態(tài)優(yōu)化編譯器。

第四默责,Java語言是可以動態(tài)擴(kuò)展的語言贬循,運(yùn)行時加載新的類可能改變程序類型的繼承關(guān)系,這使得很多全局的優(yōu)化難以進(jìn)行桃序,因為編譯器無法看清程序的全貌杖虾,許多全局的優(yōu)化都只能以激進(jìn)優(yōu)化的方式來完成,編譯器不得不時刻注意并隨著類型的變化而在運(yùn)行時撤銷或重新進(jìn)行一些優(yōu)化媒熊。

第五奇适,Java語言的對象內(nèi)存是在堆上,只有方法的局部變量才能在棧上分配芦鳍,而C/C++的對象則有多重內(nèi)存分配方式嚷往,既可能在堆上分配,又可能在棧上分配柠衅,如果可以在棧上分配線程私有的對象皮仁,將減輕內(nèi)存回收的壓力。另外菲宴,C/C++中主要由用戶用程序代碼來回收分配的內(nèi)存贷祈,這就不存在無用對象篩選的過程,因此效率上(僅是運(yùn)行效率喝峦,排除開發(fā)效率)也比Java的垃圾收集機(jī)制要高势誊。

Java 編譯器的“優(yōu)勢”

上面所了一堆Java語言在性能上的劣勢,這些都是為了換取「開發(fā)效率」上的優(yōu)勢而付出的代價谣蠢,動態(tài)安全粟耻、動態(tài)擴(kuò)展、垃圾回收這些“拖后腿”的特性眉踱,都為Java語言的開發(fā)效率做出了很大貢獻(xiàn)挤忙。

何況,還有許多優(yōu)化是Java的即時編譯器能做谈喳,而C/C++的靜態(tài)優(yōu)化編譯器不能做或者不好做的册烈。例如,在C/C++中叁执,別名分析(Alias Analysis)的難度就要遠(yuǎn)遠(yuǎn)高于Java茄厘。Java的類型安全保證了在類似如下代碼中,只要ClassA和ClassB沒有繼承關(guān)系谈宛,那對象objA和objB就絕不可能是同一個對象次哈,即不會是同一塊內(nèi)存兩個不同別名。

void foo(ClassA objA, ClassB objB) {
    objA.x = 123;
    objB.y = 456;
    // 只要objB.y不是objA.x的別名吆录,下面就可以保證輸出為123
    print(objA.x);
}

確定了objA和objB并非對方的別名后窑滞,許多與數(shù)據(jù)依賴相關(guān)的優(yōu)化才可以進(jìn)行(重排序、變量替換)。具體到這個例子中哀卫,就是無需擔(dān)心objB.y與objA.x指向同一塊內(nèi)存巨坊,這樣就可以安全地確定打印語句中的objA.x為123。

Java編譯器另外一個紅利是由它的動態(tài)性所帶來的此改,由于C/C++編譯器所有優(yōu)化都在編譯期完成趾撵,以運(yùn)行期性能監(jiān)控為基礎(chǔ)的優(yōu)化措施它都無法進(jìn)行,如:

  1. 調(diào)用頻率預(yù)測:Call Frequency Prediction
  2. 分支頻率預(yù)測:Branch Frequency Prediction
  3. 裁剪未被選擇的分支:UNtaken Branch Pruning

這些都是Java語言獨(dú)有的性能優(yōu)勢共啃。

總結(jié)

隨著Java JIT編譯技術(shù)的發(fā)展占调,Java的運(yùn)行速度已經(jīng)足夠快。Java能夠在運(yùn)行時動態(tài)加載類(可以從zip包移剪、網(wǎng)絡(luò)究珊、運(yùn)行時計算、其他文件生成)纵苛,C/C++則完全做不到這一點(diǎn)剿涮。總的來說攻人,Java的動態(tài)安全取试、動態(tài)擴(kuò)展、垃圾回收等特性贝椿,使得開發(fā)效率很高想括,并且足夠靈活陷谱;同時隨著編譯技術(shù)的不斷發(fā)展烙博,性能的劣勢正在逐漸減小。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烟逊,一起剝皮案震驚了整個濱河市渣窜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宪躯,老刑警劉巖乔宿,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異访雪,居然都是意外死亡详瑞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門臣缀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坝橡,“玉大人,你說我怎么就攤上這事精置〖瓶埽” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長番宁。 經(jīng)常有香客問我元莫,道長,這世上最難降的妖魔是什么蝶押? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任踱蠢,我火速辦了婚禮,結(jié)果婚禮上棋电,老公的妹妹穿的比我還像新娘朽基。我一直安慰自己,他們只是感情好离陶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布稼虎。 她就那樣靜靜地躺著,像睡著了一般招刨。 火紅的嫁衣襯著肌膚如雪霎俩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天沉眶,我揣著相機(jī)與錄音打却,去河邊找鬼。 笑死谎倔,一個胖子當(dāng)著我的面吹牛柳击,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播片习,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼捌肴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了藕咏?” 一聲冷哼從身側(cè)響起状知,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孽查,沒想到半個月后饥悴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盲再,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年西设,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片答朋。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡贷揽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绿映,到底是詐尸還是另有隱情擒滑,我是刑警寧澤腐晾,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站丐一,受9級特大地震影響藻糖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜库车,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一巨柒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柠衍,春花似錦洋满、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阵漏,卻和暖如春驻民,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背履怯。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工回还, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叹洲。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓柠硕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親运提。 傳聞我的和親對象是個殘疾皇子蝗柔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,848評論 25 707
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司糙捺,掛了不少诫咱,但最終還是拿到小米笙隙、百度洪灯、阿里、京東竟痰、新浪签钩、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,218評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法坏快,類相關(guān)的語法铅檩,內(nèi)部類的語法,繼承相關(guān)的語法莽鸿,異常的語法昧旨,線程的語...
    子非魚_t_閱讀 31,602評論 18 399
  • 文/嚯嚯 前言 我不知道是不是每個人都會有這種感覺拾给。上了幾年大學(xué),到最后突然發(fā)現(xiàn)兔沃,還是什么都不會蒋得!是自己沒有努力,...
    小嚯嚯閱讀 332評論 0 0
  • 寫這篇文章的時候乒疏、思緒萬千额衙,獻(xiàn)給對愛情糾結(jié)的boy and girl 。這篇文章寫的是我本人的真實故事怕吴、...
    Sunny媛媛閱讀 497評論 4 2