日期:2014-05-20  浏览次数:20658 次

正确认识java JVM与c/c++的执行效率 .JAVA就是比C++快
认为Java不能写JVM是完全错误的。JNode是一个用Java写的开源操作系统,他里面的JVM就是用Java写的。这个操作系统现在有几十兆,其中 99%的代码是用java编写,其中只有一个极小的“操作系统引导程序”是用汇编写的,我们暂时称之为booter.exe,大小为几KB。  
booter.exe的作用就是将用java写的JVM编译并装入内存,简单的说就是将JVM.class编译成JVM.exe(JVM.exe也是内存中的二进制代码,并不是真实存在的文件,我暂时称之为JVM.exe) , 这个过程花了5秒种。  

  在这个操作系统中,汇编程序只能执行1秒钟。之后汇编程序就退出内存,也再也不执行了。内存中只剩下用Java写的JVM.exe。  

  之后所有的操作都有JVM.exe来进行,JVM.exe负责将其它的Abc.class、Def.class等等编译成Abc.exe、Def.exe......操作系统正式启动。  

  JNode的官方网站上有Java写的JVM的性能和SUN的JVM进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!见: http://www.jnode.org/node/51  

结果如下:  
运行评测程序ArithOpt时:  
JNode :20ms*  
Sun J2SDK :30ms**  
  JNode的官方网站上有Java写的JVM的性能和SUN的JVM进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!见: http://www.jnode.org/node/51  

结果如下:  
运行评测程序ArithOpt时:  
JNode :20ms*  
Sun J2SDK :30ms**  
  上面JNode 中用Java写的JVM与Sun 的用C++写的JVM的比较是在Pentium4 2Ghz with 1GB of memory上比较的  

  其实,无论是c++,java,vb,delphi还是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的CPU,booter.exe也可以不需要,只要有个Booter.class就可以,这样,整个操作系统就100%都是java写的了  

  还有,就算在不支持java bytecode的cpu上,也可以用java来写booter.exe。  
原理很简单:写个 Booter.java,将它编译成Booter.class,再用Java写个“.class to .exe 编译器”,将Booter.class编译成Booter.exe,这次,Booter.exe不仅存在于内存中,还可以将它写到硬盘上。这用 Java编译出来的Booter.exe所有的功能都和用汇编写的booter.exe完全一样。  

  从此,我们就得到了一个“100%”的纯Java操作系统。  


  完全可以用Delphi写一个C++编译器,再用这个编译器去编译abc.cpp的源代码,难道编译出来的abc.exe就变成了 delphi程序吗?一个二进制代码是用什么语言写成的,是由“它是由什么编译器编译出来”决定的,而不是由“它的编译器是由什么语言写成的”决定的 所以Java程序不是C++程序,因为无论Java的编译器是用VB、perl、C++、还是汇编写成的,只要编译编译的是Abc.java的源代码,这就是个java程序。  

举个例子,有4种java编译器。一种是用VB写成的,一种是用C++写成的,一种是用Delphi写成的,一种是用Perl写成的.他们都去编译 Abc.java的源代码:  
VB 写的java编译器将Abc.java编译成Abc.class用了0.020秒  
C++ 写的java编译器将Abc.java编译成Abc.class用了0.001秒  
Delphi写的java编译器将Abc.java编译成Abc.class用了0.002秒  
Perl 写的java编译器将Abc.java编译成Abc.class用了0.040秒  
最后编译出来的Abc.class完全一样,那么这4个编译出来的Abc.class在同一个虚拟机上运行时的性能完全一样,难道这可以证明VB,C++,Delphi,Perl的性能完全一样吗?  


  再举个例子,有4种java虚拟机(JVM)。一种是用 VB写成的,一种是用C++写成的,一种是用Delphi写成的,一种是用Perl写成的.他们都去运行Abc.class的java文件。实际运行过程是这样的:JVM先把Abc.class编译成Abc.exe(其实只是内存中的二进制指令序列,没有这个文件,为了便于理解,我给出名 Abc.exe),然后CPU运行Abc.exe。由于四种JVM(VbJVM、 CppJVM,DelphiJVM、PerlJVM)编译出来的 Abc.exe完全一样,所以四种JVM在运行 Abc.exe时的性能完全一样,差距只在于:4种JVM将Abc.class编译成Abc.exe所有的“编译所花费的时间”不同。  

CppJVM 将Abc.class编译成Abc.exe花0.001秒, 然后Abc.exe运行花费300秒,共300.001秒  
VbJVM 将Abc.class编译成Abc.exe花0.010秒, 然后Abc.exe运行花费300秒,共300.010秒  
DelphiJVM将Abc.class编译成Abc.exe花0.002秒, 然后Abc.exe运行花费300秒,共300.002秒  
PerlJVM 将Abc.class编译成Abc.exe花0.020秒, 然后Abc.exe运行花费300秒,共300.020秒  

  大家可以看到,虽然VbJVM编译Abc.class的速度只是CppJVM的十分之一,但Abc.class在VbJVM和在 CppJVM上运行所花的时间几乎完全一样,难道这样能证明VB和C++性能一样?当然不能!也就是说,Java程序运行所花费的时间,与JVM是用什么写成的几乎没有关系!哪怕这个JVM是用最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最最快的语言写的,将Abc.class编译成Abc.exe只用了 0.00000000000000000000000000000000000000000000000000000000000000001 秒,最终也几乎不会影响Abc.class在这个JVM上运行的时间。