JVM的JIT优化所带来的性能提升与C++之类比较那个好

关注了一段时间@RednaxelaFX,正好最近在写C++内存相关算法,在这里根据R大的回答整理一个易懂的回答吧!相信题主并不是非常了解JVM的实现机制(我也不是非常了解),因此,对题主的问题,short answer:在某些特定的场合,JIT产生的汇编码,和用C++写一个相同功能的函数所产生的汇编码,二者可以十分接近。long answer:即使是使用JIT,并且,运行后一段时间达到一个稳定的状态(JIT下Java的性能是缓慢上升的),Java仍有几个绕不过去的坎,使得Java的速度无法超过编写出来的C++程序。1.Java的GC普遍使用check point,一个比较复杂的循环的末尾一定会有一个check point,相当于每次循环都要多做一个if判断。JIT可能可以通过profile来减少check point,但如果循环内要进行线程同步,循环末尾的check point就是无法避免的。这一项,JIT略微加分。2.多线程程序中,Java承诺严格保证指令执行顺序,而C++则不承诺,但提供了五种内存序及atomic类,这使得Java程序要频繁地发射内存屏障来保证指令顺序,并且从原理上无法避免,但C++就有充分的自主选择权。意思是,Java一揽子把事情全包了,但C++有权利选择哪些要哪些不要。JIT不像静态编译那样有足够的时间分析哪些内存屏障是不必须的,但其实静态编译也不太可能分析出哪些内存屏障是可以去掉。这一项,JIT没太大影响。3.Java严格保证表达式内的求值顺序,而C++一定程度上不保证(需要部分地人为指定)。例如,函数传参时,C++不规定参数的求值顺序,只规定入栈顺序,但Java就规定了。做加法时,例如a是一个多线程共享变量,执行a+=b+=c+=d,如果abcd都是unsigned,C++可以接受a=(a+b)+(c+d)这样的求值顺序(因为没有发射内存屏障,编译器可以考虑这样的优化),a的值是从a“突变”到a+b+c+d的,但Java就不可以接受,a一定是从a变到a+b再变到a+b+c再变到a+b+c+d的。JIT不像静态编译那样有充足的时间来分析,看表达式是否接受“乱序”。多次执行同一代码块后,JIT可能会进行优化。这一项,JIT减分。4.运行时类型识别。每生产一个类,Java就要做一些额外的工作来保证类型识别,即使只是在类的开头增加一个type id。对于一些非常小的类,静态编译可以有足够的时间把这个类放在栈上,优化这个类。JIT的行为要看具体实现。这一项,JIT不加分不减分。可以看出,对于Java这门语言的“硬伤”,JIT是无法优化的。所以理论上Java不可能比C++快,当然前提是你有无限的时间来写C++代码。
■网友
动态优化只能说和静态优化各有千秋。对于比较容易的优化,动态优化更容易利用第一手的信息;相对的静态优化可以进行更复杂的处理。Java的很多坑不是靠JIT救得了的。Java比OC快姑且还有可能,比C++快那是做梦。特定环境下的特定处理Java跑出比C++高的速度说明不了问题。Java充其量只能说在绝大多数情况下没慢到不能容忍,不得不去牺牲开发成本的程度。
■网友
不是哪个好的问题。有几个要区分的问题: 1) JVM中 JIT不是万能的,2) JIT是有开销代价的(包括Profiling和startup等等)。 3) 要是你没有多平台的限制,以及知道哪些代码优化等等,C++ 更好。
■网友
不要把两者对立起来撒~
看bing搜索引擎(排行第一答案里说的有无限时间的主顾)的选择,用C++,然后再给C++写个JIT。
BitFunnel/NativeJIT
【JVM的JIT优化所带来的性能提升与C++之类比较那个好】


    推荐阅读