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

       大多數程序員都認爲C/C++會比Java語言快,甚至覺得從Java語言誕生以來“執行速度緩慢”的帽子就應當扣在它的頭頂,這種觀點的出現是由於Java剛出現的時候即時編譯技術還不成熟,主要靠解釋器執行的Java語言性能確實比較低下。但目前即時編譯技術已經十分成熟,Java語言有可能在速度上與C/C++一爭高下嗎?要想知道這個問題的答案,就讓我們從兩者的編譯器談起。

        Java與C/C++的編譯器對比實際上代表了最經典的即時編譯器與靜態編譯器的對比,很大程度上也決定了Java與C/C++性能對比的結果,因爲無論是C/C++還是java代碼,最終編譯之後被機器執行的都是本地機器碼,哪種語言性能更高,出來她們自身的API庫實現得好壞以外,其餘比較就成了異常“拼編譯器”和“拼輸出代碼質量”的遊戲。當然這種比較也是剔除了開發效率的片面對比,語言間孰優孰劣,誰快誰慢的問題都是很難有結果的爭論,下面我們就回到正題,看看這兩種語言的編譯器各有何種優勢。

        Java虛擬機的即時編譯器與C/C++的靜態編譯器相比,可能會由於下列這些原因而導致輸出的本地代碼有一些略勢(下面列舉的也包括一些虛擬機執行子系統的性能劣勢):

        1.因爲即時編譯器運行佔用的是用戶程序的運行時間,具有很大的時間壓力,它能提供的優化手段也受制於編譯成本。如果編譯速度不能達到要求,那用戶將在啓動程序或程序的某部分察覺到重大延遲,這點使得即時編譯器不敢隨便引入大規模的優化技術,而編譯時間成本在靜態優化編譯器中並不是主要的關注點。

        2.Java語言是動態類型安全語言,這就意味着需要由虛擬機來確保程序不會違反語言語義或訪問非結構化內存。從實現層面上看,這就意味着虛擬機必須頻繁地進行動態檢查,如實例方法訪問時檢查空指針,數組元素訪問時檢查上下界範圍,類型轉換時檢查繼承關係等。對於這類程序代碼沒有明確寫出的檢查行爲,儘管編譯器會努力進行優化,但總體上仍然要消耗不少的運行時間。

        3.Java語言中雖然沒有virtual關鍵字,但是使用虛方法的頻率卻遠遠大於C/C++語言,這意味着運行時對方法接收者進行多態選擇的頻率要遠遠大於C/C++語言,也意味着即時編譯器在進行一些優化(如前面提到的方法內聯)時難度要遠大於C/C++的靜態優化編譯器。

       4.Java語言是可以動態擴展的語言,運行時加載新的類可能改變程序類型的繼承關係,這使得很多全局的優化都難以進行,因爲編譯器無法看見程序的全貌,許多全局的優化措施都只能以激進優化的方式來完成,編譯器不得不時刻注意並隨着類型的變化而在運行時撤銷或重新進行一些優化。

       5.Java語言中對象的內存分配都是在堆上進行的,只有方法中的局部變量才能在棧上分配。而C/C++的對象則有多種內存分配方式,既可能在堆上分配,又可能在棧上分配,如果可以再棧上分配線程私有的對象,將減輕內存回收的壓力。另外,C/C++中主要由用戶程序代碼來回收分配的內存,這就不存在無用對象的篩選過程,因此效率上(僅指運行效率,排除了開發效率)也比垃圾收集器要高。

      上面說了一大堆Java語言與C/C++的劣勢,不是說Java就真的不如C/C++了,相信讀者也注意到了,Java語言的這些性能上的劣勢都是爲了換區開發效率上的優勢而付出的代價,動態安全,動態擴展,垃圾回收這些拖後腿的特性都爲Java語言的開發效率做出了很大貢獻。何況,還有許多優化是Java的即時編譯器能做而C/C++的靜態編譯器補鞥呢做或者不好做的。例如:在C/C++中,別名分析的難度就要遠高於Java。Java的類型安全保證了在類似如下代碼中,只要ClassA和ClassB沒有繼承關係,那對象ObjA和ObjB就絕不可能是同一個對象,即不會是同一塊內存兩個不同的別名。

public void foo(ClassA objA,ClassB objB){
    objA.x = 123;
    objB.y = 456;
    //只要objB.y不是objA的別名,下面就可以保證輸出爲123
    System.out.println(objA.x);
}

 

       確定了objA和objB並非對方的別名後,許多與數據依賴相關的優化纔可以進行(重排序,變量代換)。具體到這個例子中,就是無須擔心objB.y其實與objA.x指向同一塊內存,這樣就可以安全地確定打印語句中的objA.x爲123。

       Java編譯器另外一個紅利是由它的動態性所帶來的,由於C/C++編譯器所有優化都在編譯期完成,以運行期性能監控爲基礎的優化措施它都無法進行,如調用頻率預測,分子頻率預測,剪裁未被選擇的分支等,這些都成爲java語言獨有的性能優勢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章