开发者

when is java faster than c++ (or when is JIT faster then precompiled)? [duplicate]

This question already has answers here: Closed 12 years ago.

Possible Duplicate:

JIT开发者_如何学运维 compiler vs offline compilers

I have heard that under certain circumstances, Java programs or rather parts of java programs are able to be executed faster than the "same" code in C++ (or other precompiled code) due to JIT optimizations. This is due to the compiler being able to determine the scope of some variables, avoid some conditionals and pull similar tricks at runtime.

Could you give an (or better - some) example, where this applies? And maybe outline the exact conditions under which the compiler is able to optimize the bytecode beyond what is possible with precompiled code?

NOTE : This question is not about comparing Java to C++. Its about the possibilities of JIT compiling. Please no flaming. I am also not aware of any duplicates. Please point them out if you are.


In practice, you're likely to find your naively written Java code outperform your naively written C++ code in these situations (all of which I've personally observed):

  • Lots of little memory allocations/deallocations. The major JVMs have extremely efficient memory subsystems, and garbage collection can be more efficient than requiring explicit freeing (plus it can shift memory addresses and such if it really wants to).

  • Efficient access through deep hierarchies of method calls. The JVM is very good at eliding anything that is not necessary, usually better in my experience than most C++ compilers (including gcc and icc). In part this is because it can do dynamic analysis at runtime (i.e. it can overoptimize and only deoptimize if it detects a problem).

  • Encapsulation of functionality into small short-lived objects.

In each case, if you put the effort in, C++ can do better (between free lists and block-allocated/deallocated memory, C++ can beat the JVM memory system in almost every specific case; with extra code, templates, and clever macros, you can collapse call stacks very effectively; and you can have small partially-initialized stack-allocated objects in C++ that outperform the JVM's short-lived object model). But you probably don't want to put the effort in.


Some examples:

  • The JIT compiler can produce very CPU-specific machine code using e.g. the newest SSE extensions that one would not use in precompiled code that needs to run one a wide range of CPUs.
  • The JIT knows when a virtual method (the default in Java) is not overwritten anywhere, and thus can be inlined (though this requires the ability to un-inline it when a new class is loaded that does overwrite the method; current Java JIT compilers actually do this).
  • Related to that, escape analysis allows seeveral situation-specific optimizations.


Wikipedia: http://en.wikipedia.org/wiki/Just-in-time_compilation#Overview

In addition, it can in some cases offer better performance than static compilation, as many optimizations are only feasible at run-time:

  1. The compilation can be optimized to the targeted CPU and the operating system model where the application runs. For example JIT can choose SSE2 CPU instructions when it detects that the CPU supports them. To obtain this level of optimization specificity with a static compiler, one must either compile a binary for each intended platform/architecture, or else include multiple versions of portions of the code within a single binary.

  2. The system is able to collect statistics about how the program is actually running in the environment it is in, and it can rearrange and recompile for optimum performance. However, some static compilers can also take profile information as input.

  3. The system can do global code optimizations (e.g. inlining of library functions) without losing the advantages of dynamic linking and without the overheads inherent to static compilers and linkers. Specifically, when doing global inline substitutions, a static compilation process may need run-time checks and ensure that a virtual call would occur if the actual class of the object overrides the inlined method, and boundary condition checks on array accesses may need to be processed within loops. With just-in-time compilation in many cases this processing can be moved out of loops, often giving large increases of speed.

  4. Although this is possible with statically compiled garbage collected languages, a bytecode system can more easily rearrange executed code for better cache utilization.


Java's memory manangement is considerably faster than C++'s. See Java theory and practice: Urban performance legends, revisited.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜