熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

正確認識java JVM與c/c++的執行效率

2013-11-23 19:31:55  來源: Java核心技術 

  認為Java不能寫JVM是完全錯誤的JNode是一個用Java寫的開源操作系統他裡面的JVM就是用Java寫的這個操作系統現在有幾十兆其中   %的代碼是用java編寫其中只有一個極小的操作系統引導程序是用匯編寫的我們暫時稱之為booterexe大小為幾KB
booterexe的作用就是將用java寫的JVM編譯並裝入內存簡單的說就是將JVMclass編譯成JVMexe(JVMexe也是內存中的二進制代碼並不是真實存在的文件我暫時稱之為JVMexe)     這個過程花了秒種

     在這個操作系統中匯編程序只能執行秒鐘之後匯編程序就退出內存也再也不執行了內存中只剩下用Java寫的JVMexe

     之後所有的操作都有JVMexe來進行JVMexe負責將其它的AbcclassDefclass等等編譯成AbcexeDefexe操作系統正式啟動

     JNode的官方網站上有Java寫的JVM的性能和SUN的JVM進行性能比較的結果JNode中用Java寫的JVM竟然能比SUN公司用C++寫的JVM還快!見  

結果如下
運行評測程序ArithOpt時
JNode   ms*
Sun   JSDK   ms**
     JNode的官方網站上有Java寫的JVM的性能和SUN的JVM進行性能比較的結果JNode中用Java寫的JVM竟然能比SUN公司用C++寫的JVM還快!見  

結果如下
運行評測程序ArithOpt時
JNode   ms*
Sun   JSDK   ms**
     上面JNode   中用Java寫的JVM與Sun   的用C++寫的JVM的比較是在Pentium   Ghz   with   GB   of   memory上比較的

     其實無論是c++javavbdelphi還是perl他們最終在cpu中執行時都是二進制代碼沒有本質區別他們的差別就在於不同的編譯器編譯出來的二進制代碼的優化程度不同用程序員直接寫出的匯編由於沒有進行深入的優化很難達到其它用java/c++/delph/vb編譯器的優化程度所以我說手寫匯編的速度達不到c++/java的速度實質就是說手寫匯編再編譯出來的二進制代碼的優化程度沒有用c++   /java編譯器編譯出來的二進制代碼的優化程度高

     底層用C++或匯編來寫並不是因為他們更快而是因為他們更節省內存操作硬件更方便VB是一種解釋語言它的內存占用量也很大而且VB中直接操作內存等硬件的方法並不多而且C++已經有許多已經成型的類庫用C++寫JVM明顯比VB強如果你感覺eclipse或永中慢就認定Java慢那麼大家感覺WindowsXP慢是不是大家就應該認定 C++慢 呢?誰快誰慢拿數據說話吧

     另外不要因為某些java程序啟動慢就認定java慢這除了因為上面說的原因外還因為
C++啟動較快也不全是因為C++本身的原因許多C++寫的軟件所需的一些exe和dll在操作系統啟動時就已經啟動了(比如和窗口相關的一些dll)
NET程序啟動較快就是因為NET的虛擬機其實在操作系統啟動時就已經啟動了
而其它一些大型軟件如Microsoft   Word啟動較快就是因為操作系統啟動時就已經啟動了和Word相關的一些服務和功能


     當然對於能直接支持java   bytecode的CPUbooterexe也可以不需要只要有個Booterclass就可以這樣整個操作系統就%都是java寫的了

     還有就算在不支持java   bytecode的cpu上也可以用java來寫booterexe
原理很簡單寫個   Booterjava將它編譯成Booterclass再用Java寫個class   to   exe編譯器將Booterclass編譯成Booterexe這次Booterexe不僅存在於內存中還可以將它寫到硬盤上這用   Java編譯出來的Booterexe所有的功能都和用匯編寫的booterexe完全一樣

     從此我們就得到了一個%的純Java操作系統


     完全可以用Delphi寫一個C++編譯器再用這個編譯器去編譯abccpp的源代碼難道編譯出來的abcexe就變成了delphi程序嗎?一個二進制代碼是用什麼語言寫成的是由它是由什麼編譯器編譯出來決定的而不是由它的編譯器是由什麼語言寫成的決定的


     所以Java程序不是C++程序因為無論Java的編譯器是用VBperlC++還是匯編寫成的只要編譯編譯的是Abcjava的源代碼這就是個java程序



     舉個例子種java編譯器一種是用VB寫成的一種是用C++寫成的一種是用Delphi寫成的一種是用Perl寫成的他們都去編譯   Abcjava的源代碼:
VB   寫的java編譯器將Abcjava編譯成Abcclass用了
C++   寫的java編譯器將Abcjava編譯成Abcclass用了
Delphi寫的java編譯器將Abcjava編譯成Abcclass用了
Perl   寫的java編譯器將Abcjava編譯成Abcclass用了
最後編譯出來的Abcclass完全一樣那麼這個編譯出來的Abcclass在同一個虛擬機上運行時的性能完全一樣難道這可以證明VBC++DelphiPerl的性能完全一樣嗎?


     再舉個例子種java虛擬機(JVM)一種是用   VB寫成的一種是用C++寫成的一種是用Delphi寫成的一種是用Perl寫成的他們都去運行Abcclass的java文件實際運行過程是這樣的JVM先把Abcclass編譯成Abcexe(其實只是內存中的二進制指令序列沒有這個文件為了便於理解我給出名   Abcexe)然後CPU運行Abcexe由於四種JVM(VbJVMCppJVMDelphiJVMPerlJVM)編譯出來的   Abcexe完全一樣所以四種JVM在運行   Abcexe時的性能完全一樣差距只在於種JVM將Abcclass編譯成Abcexe所有的編譯所花費的時間不同

CppJVM   將Abcclass編譯成Abcexe花   然後Abcexe運行花費
VbJVM   將Abcclass編譯成Abcexe花   然後Abcexe運行花費
DelphiJVM將Abcclass編譯成Abcexe花   然後Abcexe運行花費
PerlJVM   將Abcclass編譯成Abcexe花   然後Abcexe運行花費

     大家可以看到雖然VbJVM編譯Abcclass的速度只是CppJVM的十分之一但Abcclass在VbJVM和在CppJVM上運行所花的時間幾乎完全一樣難道這樣能證明VB和C++性能一樣?當然不能!也就是說Java程序運行所花費的時間與JVM是用什麼寫成的幾乎沒有關系!哪怕這個JVM是用最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最快的語言寫的將Abcclass編譯成Abcexe只用了   最終也幾乎不會影響Abcclass在這個JVM上運行的時間

     最終得出結論Java的速度與JVM是用什麼語言寫成的幾乎沒有關系


     而Java的本地代碼是用Java的JIT和HotSpot編譯器在程序運行時編譯出來的根本不是C++編譯器編譯出來的所以java程序根本不是一個C++程序!


     JIT和HotSpot編譯器可以根據程序運行的CPU進行指令集進行優化C++編譯器可以嗎?
     JIT和HotSpot編譯器可以根據程序運行時的profile對本地代碼進行inline等優化C++編譯器可以嗎?
     JIT和HotSpot編譯器可以根據程序運行時根據程序運行的情況進行更准確的分支預測C++編譯器可以嗎?


     大家可以去jre的安裝路徑中去看看
其中的jar文件共有50由於jar文件是壓縮文件並且bytecode的代碼要比native   code精簡的多(前面已經說過了一個構造方法在bytecode中只要一個指令構造方法在C++的編譯器卻要個指令Java   一個   method   call   只要一個machine   code但用   x   相對需要     個)所以這50M的java程序完成的工作大約相當於200M以上的本地代碼完成的工作
而其中的exe和dll共有M本地代碼在java運行環境中占的比例連5%都不到

     而這僅有的5%的C++編譯器產生的本地代碼(比如AWTdll)在java程序運行時還要被JIT和HotSpot編譯器重新編譯成新的指令序列   (例如符合SSE的指令集的指令)並根據運行時的profile   來內聯到其它java編譯器編譯出來的native   code中成為全新的NativeCode序列

     所以C++編譯器編譯出來java本地庫的機器代碼序列在java運行的時候根本看不到這些機器代碼也被Java的JIT和HotSpot編譯器重新編譯並更改執行序列這些C++編譯器編譯出來的機器代碼已經變成了Java編譯器編譯出來的機器代碼最終在CPU中執行的所有機器語言序列全部是由Java編譯器產生的與C++編譯器沒有一點關系


     C++的速度是由C++編譯器在程序員開發時編譯出來的機器語言的優化程度決定的
Java的速度是由Java的JIT和HotSpot編譯器將java   bytecode在運行時即時編譯成針對本地CPU的優化的本地代碼決定的

     比速度的實際就是在比看C++編譯器和java編譯器誰能產生更優化的機器代碼
很明顯C++的編譯器不如java的JIT和HotSpot編譯器因為JIT和HotSpot編譯器能針對CPU指令集進行人優化能在運行時根據使用頻率對method進行內聯和優化而C++的靜態編譯器永遠也做不到這些

     兩者有著本質的不同但是有些人用一輩子也無法理解這其中的差別
他們只能抱著一個可憐的沒有任何根據C++比Java快終其一生


From:http://tw.wingwit.com/Article/program/Java/hx/201311/27049.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.