`
Eastsun
  • 浏览: 304582 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

JAVA比C++更快?

阅读更多
首先:我必须承认,我取JAVA比C++更快?为标题是有点故意吸引眼球的意思.
   事实上在本文中,我的主要目的不是为了证明或否定JAVA比C++更快这一个结论(事实上标题中的"?"已经隐含了这一点),而是通过引用几位JAVA大牛的文章深入JIT与Hotspot的实现原理,来说明为什么JAVA可以比C++更快.当然,在你有你自己的结论之前,我希望你能仔细看一下文中引用的几篇文章,而不是想当然.
    注意:文中大部分内容或结论是引用别人的文章,有一些是我自己的看法,文中用绿色标出.
   1.静态编译与Hotspot动态编译

    我们知道,C++相对Basic等解释型语言,之所以性能上有明显的优势,主要是因为C++在运行的时候已经通过编译器编译为二进制的机器语言,并且现代的编译器可以在编译的时候做大量的最优化处理;而Basic等解释型语言运行的时候是通过解释器一步步的解释运行,这样中间隔了一个解释器,速度当然就慢了.
    而JAVA刚出世的时候采取的也是解释执行的方法(现在某些低端设备上的JRE还是解释执行),只不过它比Basic更聪明一点:不是直接解释JAVA源代码,而是先将JAVA源代码编译为一种平台无关的JAVA字节码.这样执行速度可能会比Basic快一些,但相对C++的执行效率还是有很大的差别.
    然后,JIT(just-in-time)编译器出现了.JIT编译器在每段代码执行前进行编译,编译的结果为本地静态机器码,执行速度有了质的提高.到这儿,我们可以比较一下C++的静态编译与JRE的JIT静态编译:一个是在运行前将代码编译为机器语言,一个是在运行时将字节码编译为机器语言,相比而言,JAVA的JIT编译器还是显得笨一点,预先一次编译比运行时再编译当然要好了.但对于JAVA,为了跨平台,这样做是必须的.
    JIT静态编译器相对解释执行已经有了很大的提高,但是性能仍然和C++有很大的差距.对一段程序,一名优秀的程序员是如何来改进运行速度的呢?首先,他不会傻到把所有的代码都来优化,他会观察、思考到底哪段代码对整体性能影响最大?然后集中精力来优化这一段代码.按照经验,整个程序 10%-20%的代码,会占据 80%-90%的运行时间.用这种方法,在同样的时间、付出同样程度的努力后,这名优秀的程序员使整个程序的性能得到了很大程度的优化.HotSpot引擎,就是模仿人工的这种方法进行优化的.在程序运行的开始,Java代码仍然解释执行,但HotSpot引擎开始进行采样(Profiling).根据采样的结果,决定某段程序是占用较多运行时间的,就认为它是“HotSpot”,它也就是目前程序的瓶颈,引擎开始启动一个单独的线程进行优化.因为不象原始的 JIT编译器那样无差别的编译所有代码,HotSpot引擎可以集中精力来对HotSpot代码进行深度优化,这样这部分代码执行起来更加迅捷.


   2.让我们来看看JIT/Hotspot的工作

    一般来说,JVM或JAVA的标准API没有提供让我们观察Hotspot工作(产生机器码)的接口.所以以前我们只能猜测Hotspot在背后究竟做了那些事情,我们写的JAVA代码被它弄成什么样子了.
    不过现在好了,Java SE Update N这一系列因为处于开发状态,为了方便debug,这些JVM提供了一个运行参数:PrintOptoAssembly,你可以通过如下方式:
引用

java -XX:+PrintOptoAssembly -server -cp . Main

运行你的程序,就可以看到这些JAVA程序在编译为机器语言之后的样子.
    Kohsuke Kawaguchi做了一些测试,他在博客深入JAVA生成的机器码(Deep dive into assembly code from Java)中进行了一些展示与讲解.并且他对JVM生成的优化代码表示赞赏:
引用
All in all, modern JVMs seem pretty good at generating optimal code. In various situations, the resulting assembly code is far from the straight-forward instruction-by-instruction translation.


     JAVA之父James Gosling在他的博客Hotspot performance中描述了JIT/Hotspot生成的机器码有以下优点:
引用

   ◇ Really aggressive inlining
   ◇ Even storage allocation & initialization gets inlined - new T() really is as efficient as C's alloca() (and it beats the pants off malloc())
   ◇ Careful management of cache prefetching
   ◇ Deep understanding of variablity between the flavors of x86 machines
   ◇ Loop unrolling with warmup/cooldown
   ◇ "theorum proving away" of array index checks (and many other things)
   ◇ much cleverness with locks





3.JVM的执行效率可以比C++更高?

     事实上,我认为现在将JAVA与C++比较执行效率没什么太多的意义了.我的意思是,JAVA已经足够快了.而且说实话,经过学C++再学JAVA之后,我已经对C++这门语言避而远之了.
     不过为了满足一下某些人的八卦精神,我这里给出几个JAVA与C++的比较:
     The Java is Faster than C++ and C++ Sucks Unbiased Benchmark
     FreeTTS - A Performance Case Study
     Performance comparison C++, C# and Java
     八卦之后,我们来看看为什么JAVA能过这么快呢?
     同样,给出几篇介绍JIT/Hotspot工作原理的文章:
     JIT Performance: Defying Physics?
      Can JIT'ed Code be Faster than Hardware Accelleration


分享到:
评论
1 楼 Emy 2008-05-12  
也是,学过c++再学java~·
我现在就是对c+避而远之~~

相关推荐

    在什么情况下Java比C++快?

    在什么情况下Java比C++快?  回复者:Cameron Purdy,Oracle中间件高级工程师。  这是根据我同时使用C++和Java工作超过20年所学到的,其实使用Java比C++还要早几年:  1、根据我的经验,当你把优化过的C++代码...

    C++和java作为编程语言的区别解析,用C++开发益智游戏代码的过程说明.docx

    但是,C++程序在编译时可以进行更多的优化,因此通常比Java程序运行得更快。 其次,C++允许程序员使用指针,这是一种非常强大但也很危险的编程特性。指针可以使程序员直接访问内存地址,这可以带来更高的性能和更大...

    C++ 标准程序库.pdf

    C++是2015年上半年同比增长最快的编程语言。具体为C++ 增长3.1%,Java 增长2.0%,C#增长1.6%,Python增长1.6%。C++大幅度增长的原因可能是引入了新的C++11标准。这使得C++被大范围的接受。C++ 11标准为C++带来了很多...

    轻量级C++插件框架

    通过使用 SWIG,可与 Python、Java 等语言进行集成(当然可以单独使用C++)。 使用此框架可以快速开发出更多的插件和应用软件,此框架已在 Windows/Linux/MacOSX 上测试过。 要在 Windows 上编译和运行,请参考 ...

    C++精华资料全集——云盘链接

    Reason :跨平台的框架,使开发者能够更容易地使用Java,.Net和Python,同时也满足了他们对C++性能和优势的需求。 ROOT :具备所有功能的一系列面向对象的框架,能够非常高效地处理和分析大量的数据,为欧洲原子能...

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目源代码

    Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来...

    java开源包11

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包6

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包4

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包101

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包9

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java基础入门教程

    另 外 ,由 JavaSoft 推 出 的 完 全 用 Java编 写 的 Internet上 新 型 浏览器 HotJava,比 去 年alpha版 更 为 实 用 ,不 仅 能 编 制 动 态 的 应 用 软件 ,而 且 能 编 制 完整 的 成 套 桌 面 应 用软 件 ,将 来 ...

    java开源包5

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包8

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包10

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    Java I/O学习笔记: 磁盘操作 字节操作 字符操作 对象操作 网络操作 NIO & AIO Java I/O

    Java编程语言的语法类似于C++,但是相比C++更简洁和易于理解。它采用了“一次编写,到处运行”的原则,即一次编写的程序可以在不同的操作系统上运行,这得益于Java虚拟机(JVM)的存在。JVM是Java的核心组成部分,它...

    java学习重点

    更快的开发程序 4 完全的OO(面向对象,单根结构) 的跨平台语言; 用纯Java编写的程序可以避免平台相关性; 5 分布式开发,支持多线程,可靠安全健壮; 一次编写,处处运行,可以更容易的发布软件; 3、主要的开源...

    C#调用java组件SatJni1.2

    C#直接调用java类(jar或.class文件),无需转化为.net组件,更快速、稳定 SatJni是C++编写的动态链接库,实现了C#,PB,Delphi,VB,VC等对Java的调用,能让你很容易地调用成熟的java类库和第三方java组件。不用再为移值...

    java开源包3

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

Global site tag (gtag.js) - Google Analytics