首先:我必须承认,我取
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
分享到:
相关推荐
在什么情况下Java比C++快? 回复者:Cameron Purdy,Oracle中间件高级工程师。 这是根据我同时使用C++和Java工作超过20年所学到的,其实使用Java比C++还要早几年: 1、根据我的经验,当你把优化过的C++代码...
Java的跨平台能力也是其一大优势,而C++更依赖于特定的硬件和操作系统。 总之,Java和C++各有优缺点,适用于不同的开发需求。选择哪种语言取决于项目的需求、团队的技能集和开发目标。理解它们之间的联系和区别,有...
总之,C++转换JAVA工具在多语言开发环境中扮演着重要角色,帮助开发者克服语言之间的障碍,实现更高效、更灵活的软件开发。了解和掌握这类工具的使用,对于提升开发效率和项目质量具有重要意义。
由于读者已掌握C/C++的基础知识,本教程将通过比较的方式,强调Java与C/C++之间的相似之处与不同之处,从而帮助读者更快地理解和掌握Java的基本概念和技术要点。 #### 为什么选择本教程 如果你已经熟悉C或C++,...
这本书《C++ for Java Programmers》是为具有一定经验的Java程序员所写,目的是让他们利用现有...通过对比Java语言,本书强调了C++的优势和特性,并在书中穿插了丰富的实例和练习,让读者能够更好地理解C++语言的精髓。
标题中的“在什么情况下Java比C快?”是一个有趣的话题,涉及到计算机编程语言性能的讨论。Java和C语言都是广泛使用的编程语言,但它们在性能上有显著的差异。C语言以其低级特性和直接操作硬件的能力而闻名,通常被...
本文将深入探讨JAVA与C++的区别、各自的优缺点以及适用场景,帮助读者更好地理解这两种语言,并作出合适的选择。 #### JAVA与C++ **JAVA** 是一种广泛使用的面向对象的编程语言,由Sun Microsystems开发并在1995年...
5. **JAVA比C++更快?** 这个话题探讨了Java是否在性能上超越了C++。Java通过即时编译(JIT)和垃圾回收机制在某些场景下可能展现出优于C++的性能,但具体情况取决于应用类型和优化程度。 6. **闭包能让JAVA语言变得...
- Java 和 C++都需要通过关键字(Java 的 class,C++的 class 或 struct)来定义类,类中包含数据成员(fields)和成员函数(methods)。在 C++中,struct 默认成员是公有的(public),而在 Java 和 C++的 class 中...
- **性能:**由于C++允许开发者进行底层操作,因此在某些情况下,C++程序可以比Java程序更高效。 - **控制力:**C++提供了对内存管理、类型转换等方面的精细控制,使得开发者能够在必要时优化程序性能。 - **广泛的...
C、C++、VB(Visual Basic)、Java和C#都是广泛应用的编程语言,每种都有其独特的优势和适用场景。 C语言是基础且强大的低级编程语言,它的语法简洁,对内存管理有直接控制,因此在系统编程、嵌入式开发和游戏引擎...
在现代软件开发中,多线程技术已经成为必不可少的一部分,特别是在JAVA和C++这样的高级编程语言中。多线程允许程序同时执行多个任务,提高应用程序的响应性和效率。本资源主要探讨了如何在JAVA和C++中实现多线程,...
- **封装**:Java和C++都提供了私有成员变量和方法来实现封装,而Object Pascal则使用了类似的机制,但其组件模型提供了更高级别的封装。 - **继承**:Java和C++都支持单继承和多继承,尽管Java在多继承方面采用了...
它以其优秀的压缩比和快速的解压速度而闻名,被很多编程语言实现,包括Java、C++和C。下面将详细解释LZMA压缩算法的基本原理以及在Java、C++和C中的实现。 1. LZMA压缩算法原理: LZMA的核心思想是基于滑动窗口的...
《C++&Java电子教程》是一份专为初学者设计的综合学习资源,涵盖了C++和Java这两种重要的编程语言的基础知识。这份教程旨在帮助零基础的学习者快速入门,理解编程的基本概念,掌握这两种语言的核心技能。 C++是...
最后,Java的设计模式(Design Patterns)是软件工程中用于解决特定问题的通用方案的模板,帮助开发人员更快地设计出稳定、可维护的系统。设计模式在Java社区中被广泛应用,也是提升Java开发能力的重要一环。
从C++过渡到Java,开发者需要注意以下几个关键点,以便更好地适应纯面向对象的Java编程。 1. **内存管理与垃圾回收** 在C++中,程序员需要手动进行内存分配和释放,而Java则采用了自动垃圾回收机制。Java的垃圾...