Q.1. What free compiler produces the most optimal Java bytecode?
Q.2. What free virtual machine executes Java bytecode the fastest (on 64-bit multi-core CPUs)?
Q.3. What other (currently active) compiler projects are missing from this list:
http://www.ibm.com/developerworks/java/jdk/
http://gcc.gnu.org/java/
http://openjdk.java.net/groups/compiler/
http://java.sun.com/javase/downloads/
http://download.eclipse.org/eclipse/downloads/
Q.4. What performance improvements can compilers do that JITs cannot (or do not)?
Q.5. Where are some recent benchmarks, comparisons, or shoot-outs (for Q1 or Q2)?
Thank you!
Q.1. What free compiler produces the fastest executable Java bytecode?
Question doesn't really make sense. The bytecode is not executed. The compiled bytecode will not be different enough to influence the efficiency of the produced machine code when using a good JIT.
Q.2. What free virtual machine executes Java bytecode the fastest (on 64-bit multi-core CPUs)?
This is a better question. I believe it's JRockit
Q.3. What other (currently active) compiler projects are missing from this list:
http://www.ibm.com/developerworks/java/jdk/
http://gcc.gnu.org/java/
http://openjdk.java.net/groups/compiler/
http://java.sun.com/javase/downloads/
http://download.eclipse.org/eclipse/downloads/
I believe you missed out JRockit. But for a more complete list, I'd look at Wikipedia: List of Java Virtual Machines. Looking up whether or not they're active should be an easy task.
Q.4. What performance improvements can compilers do that JITs cannot (or do not)?
Technically none I suppose. The bytecode compilation is basically the wrong place to put the effort when it comes to optimization.
Q.5. Where are some recent benchmarks, comparisons, or shoot-outs (for Q1 or Q2)?
Google is your friend here. These are two:
http://jmob.ow2.org/jvm/RUBiS.html
http://jmob.ow2.org/jvm/VolanoMark.html
unfortunately those don't cover that many VMs.
Q.4. What performance improvements can compilers do that JITs cannot (or do not)?
A JIT compiler can perform global optimizations. A bytecode compiler cannot do this because it cannot see all of the libraries that are loaded during the running of the program.
A JIT compiler can perform branch optimizations based on the observed behavior of the current program execution. A bytecode compiler cannot do this because by the time the program starts running the compiler is already out of the picture.
The only viable alternative to javac at the moment is the Eclipse compiler.
Have a look at it. Question is what you have found to be inefficient and if it really matters.
Related
A green-hand in Java.
I'm using Azul System's Falcon JIT compiler. Is it possible to dump decision of choosing what optimization passes to run on the hotspot code?
Moreover, in Oracle's JVM, is it possible to add option to java to show what optimizaiton passes are chosen to optimize the hotspot code?
I'm not familiar with java's toolchain and infrastructure literally.
edit:
Here optimization passes I mean are Transforming passes like function inlining, dead code elimination, constant propogation and some Analysis passes like callgraph analysis for interprocedure optimization and escape analysis for allocating objects in stack and eliminating synchronization operation.
My purpose is to learn some transformations Falcon compiler does in the LLVM IR. By using java -XX:FalconIRDumpRoot=./falcon-ir/ -XX:FalconDumpIRToDiskOf=* myClassName, Falcon compiler can dump .ll and .opt.ll if hotspots are observed. The former LLVM IR is not optimized while the latter IR is optimized using some intrinsics introduced by Azul's LLVM fork which is called "Orca" to replace the init call for object initilization. Since I can use -debug-pass-manager(for new pass manager) or --debug-pass=Structure(for legacy pass manager) in LLVM to print what optimization passes are used during the compilation, I wonder whether Falcon compiler or Azul JVM also provide such options to show what optimization Falcon decide to use for hotspot code.
the documentation of Falcon compiler only provide some option to dump IR for Azul Support to assist in analyzing performance issues. It's a blackbox. And I have just find some technique reports for some passes, like Escape Analysis and VM callbacks to acquire information from VM. Is there any other JIT compiler like Falcon whose backend is also based on LLVM and using GC to manage memory and most importantly able to print optimization decision when running? Language is not limited to Java.
Printing compilation levels and tracing particular compilation phases are both wanted, since I'm now using Falcon as a blackbox.
#Qingwei Li I did not understand clearly what passses you talking about. But if you talking about GC options for JVM tuning and seeing.
For Azul -Xloggc:gclogfile_%t_%p.log help you look into option you using. You can use https://docs.azul.com/prime/diagnosing-java-performance-problems-with-gc-log-analyzer.html to analyze the log file option.
OR you can use this -Xlog:gc,safepoint:gc.log::filecount=0
if you want log in one file.
In Oracle JVM, -Xlog:gc,safepoint:gc.log::filecount=0
Let me know if I understood right. Hope this can help you.
I've been thinking about it lately, and it seems to me that most advantages given to JIT compilation should more or less be attributed to the intermediate format instead, and that jitting in itself is not much of a good way to generate code.
So these are the main pro-JIT compilation arguments I usually hear:
Just-in-time compilation allows for greater portability. Isn't that attributable to the intermediate format? I mean, nothing keeps you from compiling your virtual bytecode into native bytecode once you've got it on your machine. Portability is an issue in the 'distribution' phase, not during the 'running' phase.
Okay, then what about generating code at runtime? Well, the same applies. Nothing keeps you from integrating a just-in-time compiler for a real just-in-time need into your native program.
But the runtime compiles it to native code just once anyways, and stores the resulting executable in some sort of cache somewhere on your hard drive. Yeah, sure. But it's optimized your program under time constraints, and it's not making it better from there on. See the next paragraph.
It's not like ahead-of-time compilation had no advantages either. Just-in-time compilation has time constraints: you can't keep the end user waiting forever while your program launches, so it has a tradeoff to do somewhere. Most of the time they just optimize less. A friend of mine had profiling evidence that inlining functions and unrolling loops "manually" (obfuscating source code in the process) had a positive impact on performance on his C# number-crunching program; doing the same on my side, with my C program filling the same task, yielded no positive results, and I believe this is due to the extensive transformations my compiler was allowed to make.
And yet we're surrounded by jitted programs. C# and Java are everywhere, Python scripts can compile to some sort of bytecode, and I'm sure a whole bunch of other programming languages do the same. There must be a good reason that I'm missing. So what makes just-in-time compilation so superior to ahead-of-time compilation?
EDIT To clear some confusion, maybe it would be important to state that I'm all for an intermediate representation of executables. This has a lot of advantages (and really, most arguments for just-in-time compilation are actually arguments for an intermediate representation). My question is about how they should be compiled to native code.
Most runtimes (or compilers for that matter) will prefer to either compile them just-in-time or ahead-of-time. As ahead-of-time compilation looks like a better alternative to me because the compiler has more time to perform optimizations, I'm wondering why Microsoft, Sun and all the others are going the other way around. I'm kind of dubious about profiling-related optimizations, as my experience with just-in-time compiled programs displayed poor basic optimizations.
I used an example with C code only because I needed an example of ahead-of-time compilation versus just-in-time compilation. The fact that C code wasn't emitted to an intermediate representation is irrelevant to the situation, as I just needed to show that ahead-of-time compilation can yield better immediate results.
Greater portability: The
deliverable (byte-code) stays
portable
At the same time, more platform-specific: Because the
JIT-compilation takes place on the
same system that the code runs, it
can be very, very fine-tuned for
that particular system. If you do
ahead-of-time compilation (and still
want to ship the same package to
everyone), you have to compromise.
Improvements in compiler technology can have an impact on
existing programs. A better C
compiler does not help you at all
with programs already deployed. A
better JIT-compiler will improve the
performance of existing programs.
The Java code you wrote ten years ago will run faster today.
Adapting to run-time metrics. A JIT-compiler can not only look at
the code and the target system, but
also at how the code is used. It can
instrument the running code, and
make decisions about how to optimize
according to, for example, what
values the method parameters usually
happen to have.
You are right that JIT adds to start-up cost, and so there is a time-constraint for it,
whereas ahead-of-time compilation can take all the time that it wants. This makes it
more appropriate for server-type applications, where start-up time is not so important
and a "warm-up phase" before the code gets really fast is acceptable.
I suppose it would be possible to store the result of a JIT compilation somewhere, so that it could be re-used the next time. That would give you "ahead-of-time" compilation for the second program run. Maybe the clever folks at Sun and Microsoft are of the opinion that a fresh JIT is already good enough and the extra complexity is not worth the trouble.
The ngen tool page spilled the beans (or at least provided a good comparison of native images versus JIT-compiled images). Executables that are compiled ahead-of-time typically have the following benefits:
Native images load faster because they don't have much startup activities, and require a static amount of fewer memory (the memory required by the JIT compiler);
Native images can share library code, while JIT-compiled images cannot.
Just-in-time compiled executables typically have the upper hand in these cases:
Native images are larger than their bytecode counterpart;
Native images must be regenerated whenever the original assembly or one of its dependencies is modified.
The need to regenerate an image that is ahead-of-time compiled every time one of its components is a huge disadvantage for native images. On the other hand, the fact that JIT-compiled images can't share library code can cause a serious memory hit. The operating system can load any native library at one physical location and share the immutable parts of it with every process that wants to use it, leading to significant memory savings, especially with system frameworks that virtually every program uses. (I imagine that this is somewhat offset by the fact that JIT-compiled programs only compile what they actually use.)
The general consideration of Microsoft on the matter is that large applications typically benefit from being compiled ahead-of-time, while small ones generally don't.
Simple logic tell us that compiling huge MS Office size program even from byte-codes will simply take too much time. You'll end up with huge starting time and that will scare anyone off your product. Sure, you can precompile during installation but this also has consequences.
Another reason is that not all parts of application will be used. JIT will compile only those parts that user care about, leaving potentially 80% of code untouched, saving time and memory.
And finally, JIT compilation can apply optimizations that normal compilators can't. Like inlining virtual methods or parts of the methods with trace trees. Which, in theory, can make them faster.
Better reflection support. This could be done in principle in an ahead-of-time compiled program, but it almost never seems to happen in practice.
Optimizations that can often only be figured out by observing the program dynamically. For example, inlining virtual functions, escape analysis to turn stack allocations into heap allocations, and lock coarsening.
Maybe it has to do with the modern approach to programming. You know, many years ago you would write your program on a sheet of paper, some other people would transform it into a stack of punched cards and feed into THE computer, and tomorrow morning you would get a crash dump on a roll of paper weighing half a pound. All that forced you to think a lot before writing the first line of code.
Those days are long gone. When using a scripting language such as PHP or JavaScript, you can test any change immediately. That's not the case with Java, though appservers give you hot deployment. So it is just very handy that Java programs can be compiled fast, as bytecode compilers are pretty straightforward.
But, there is no such thing as JIT-only languages. Ahead-of-time compilers have been available for Java for quite some time, and more recently Mono introduced it to CLR. In fact, MonoTouch is possible at all because of AOT compilation, as non-native apps are prohibited in Apple's app store.
I have been trying to understand this as well because I saw that Google is moving towards replacing their Dalvik Virtual Machine (essentially another Java Virtual Machine like HotSpot) with Android Run Time (ART), which is a AOT compiler, but Java usually uses HotSpot, which is a JIT compiler. Apparently, ARM is ~ 2x faster than Dalvik... so I thought to myself "why doesn't Java use AOT as well?".
Anyways, from what I can gather, the main difference is that JIT uses adaptive optimization during run time, which (for example) allows ONLY those parts of the bytecode that are being executed frequently to be compiled into native code; whereas AOT compiles the entire source code into native code, and code of a lesser amount runs faster than code of a greater amount.
I have to imagine that most Android apps are composed of a small amount of code, so on average it makes more sense to compile the entire source code to native code AOT and avoid the overhead associated from interpretation / optimization.
It seems that this idea has been implemented in Dart language:
https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf
JIT compilation is used during development, using a compiler that is especially fast. Then, when an app is ready for release, it is compiled AOT. Consequently, with the help of advanced tooling and compilers, Dart can deliver the best of both worlds: extremely fast development cycles, and fast execution and startup times.
One advantage of JIT which I don't see listed here is the ability to inline/optimize across separate assemblies/dlls/jars (for simplicity I'm just going to use "assemblies" from here on out).
If your application references assemblies which might change after install (e. g. pre-installed libraries, framework libraries, plugins), then a "compile-on-install" model must refrain from inlining methods across assembly boundaries. Otherwise, when the referenced assembly is updated we would have to find all such inlined bits of code in referencing assemblies on the system and replace them with the updated code.
In a JIT model, we can freely inline across assemblies because we only care about generating valid machine code for a single run during which the underlying code isn't changing.
The difference between platform-browser-dynamic and platform-browser is the way your angular app will be compiled.
Using the dynamic platform makes angular sending the Just-in-Time compiler to the front-end as well as your application. Which means your application is being compiled on client-side.
On the other hand, using platform-browser leads to an Ahead-of-Time pre-compiled version of your application being sent to the browser. Which usually means a significantly smaller package being sent to the browser.
The angular2-documentation for bootstrapping at https://angular.io/docs/ts/latest/guide/ngmodule.html#!#bootstrap explains it in more detail.
i know that java programs are first compiled and a bytecode is generated which is platform independent. But my question is why is this bytecode interpreted in the next stage and not compiled even though compilation is faster than interpretation in general??
You answered your own question. Byte code is platform independent. If the compiled code was executed then it would not work on every OS. This is what C does and it is why you have to have one version for every OS.
As others have suggested, the JVM does actually compile the code using JIT. It is just not saved anywhere. Here is a nice quote to sum it up
In a bytecode-compiled system, source code is translated to an
intermediate representation known as bytecode. Bytecode is not the
machine code for any particular computer, and may be portable among
computer architectures. The bytecode may then be interpreted by, or
run on, a virtual machine. The JIT compiler reads the bytecodes in
many sections (or in full rarely) and compiles them interactively into
machine language so the program can run faster
The Java bytecode normally is compiled via Just-In-Time (JIT) compilation.
So you still end up with fully compiled native code being executed, the only difference is that this native code is generated by the JVM at runtime, rather than being statically generated at the time the source code is compiled (as would happen with C/C++).
This gives Java two big advantages:
By delaying the compilation until runtime, the bytecode remains fully portable across platforms
In some cases the JIT compiler can actually generate more optimised native code because it is able to exploit statistics gathered by examining the execution parths of the code at runtime.
The downside, of course, is that the JIT compiler needs to do it's work at application start-up, which explains why JVM applications can have a slightly long start-up time compared to natively compiled apps.
The basic premise of your question is not true. Most modern Java virtual machines do compile frequently-executed parts of the code into native machine code.
This is known as just-in-time compilation, or JIT for short.
A pretty good introduction to relevant Sun's (now Oracle's) technology can be found here.
The JVM uses Just in time compilation http://en.wikipedia.org/wiki/Just-in-time_compilation, so it's much faster than pure interpretation.
Byte code is platform independent. Once compiled into bytecode, it could run on any system.
As it says on Wikipedia,
Just-in-time compilation (JIT), also known as dynamic translation, is
a method to improve the runtime performance of computer programs.
I recommend you to read this article. Its gives the basic working of JIT compiler for Java VM.
JIT compilers alter the role of the VM a little by directly compiling
Java bytecode into native platform code, thereby relieving the VM of
its need to manually call underlying native system services. The
purpose of JIT compilers, however, isn't to allow the VM to relax. By
compiling bytecodes into native code, execution speed can be greatly
improved because the native code can be executed directly on the
underlying platform.
When JIT compiler is installed, instead of the VM calling the
underlying native operating system, it calls the JIT compiler. The JIT
compiler in turn generates native code that can be passed on to the
native operating system for execution. The primary benefit of this
arrangement is that the JIT compiler is completely transparent to
everything except the VM.
As far as I understand Java compiles to Java bytecode, which can then be interpreted by any machine running Java for its specific CPU. Java uses JIT to interpret the bytecode, and I know it's gotten really fast at doing so, but why doesn't/didn't the language designers just statically compile down to machine instructions once it detects the particular machine it's running on? Is the bytecode interpreted every single pass through the code?
The original design was in the premise of "compile once run anywhere". So every implementer of the virtual machine can run the bytecodes generated by a compiler.
In the book Masterminds for Programming, James Gosling explained:
James: Exactly. These days we’re
beating the really good C and C++
compilers pretty much always. When you
go to the dynamic compiler, you get
two advantages when the compiler’s
running right at the last moment. One
is you know exactly what chipset
you’re running on. So many times when
people are compiling a piece of C
code, they have to compile it to run
on kind of the generic x86
architecture. Almost none of the
binaries you get are particularly well
tuned for any of them. You download
the latest copy of Mozilla,and it’ll
run on pretty much any Intel
architecture CPU. There’s pretty much
one Linux binary. It’s pretty generic,
and it’s compiled with GCC, which is
not a very good C compiler.
When HotSpot runs, it knows exactly
what chipset you’re running on. It
knows exactly how the cache works. It
knows exactly how the memory hierarchy
works. It knows exactly how all the
pipeline interlocks work in the CPU.
It knows what instruction set
extensions this chip has got. It
optimizes for precisely what machine
you’re on. Then the other half of it
is that it actually sees the
application as it’s running. It’s able
to have statistics that know which
things are important. It’s able to
inline things that a C compiler could
never do. The kind of stuff that gets
inlined in the Java world is pretty
amazing. Then you tack onto that the
way the storage management works with
the modern garbage collectors. With a
modern garbage collector, storage
allocation is extremely fast.
Java is commonly compiled to machine instructions; that's what just-in-time (JIT) compilation is. But Sun's Java implementation by default only does that for code that is run often enough (so startup and shutdown bytecode, that is executed only once, is still interpreted to prevent JIT overhead).
Bytecode interpretation is usually "fast enough" for a lot of cases. Compiling, on the other hand, is rather expensive. If 90% of the runtime is spent in 1% of the code it's far better to just compile that 1% and leave the other 99% alone.
Static compiling can blow up on you because all the other libraries you use also need to be write-once run everywhere (i.e. byte-code), including all of their dependencies. This can lead to a chain of compilations following dependencies that can blow up on you. Compiling only the code as (while running) the runtime discovers it actually needs that section of code compiled is the general idea I think. There may be many code paths you don't actually follow, especially when libraries come into question.
Java Bytecode is interpreted because bytecodes are portable across various platforms.JVM, which is platform dependent,converts and executes bytecodes to specific instruction set of that machine whether it may be a Windows or LINUX or MAC etc...
One important difference of dynamic compiling is that it optimises the code base don how it is run. There is an option -XX:CompileThreshold= which is 10000 by default. You can decrease this so it optimises the code sooner, but if you run a complex application or benchmark, you can find that reducing this number can result in slower code. If you run a simple benchmark, you may not find it makes any difference.
One example where dynamic compiling has an advantage over static compiling is inlining "virtual" methods, esp those which can be replaced. For example, the JVM can inline up to two heavily used "virtual" methods, which may be in a separate jar compiled after the caller was compiled. The called jar(s) can even be removed from the running system e.g. OSGi and have another jar added or replace it. The replacement JAR's methods can then be inlined. This can only be achieved with dynamic compiling.
I want to download a JIT compiler for Java. Where can I get a good JIT compiler?
The JIT compiler runs as part as the JVM - it's not something you download and run separately.
In the early days of Java, you used to be able to run a JIT as a plugin - but these days there's no need. Any mainstream, modern desktop Java environment will include a JIT.
Most of the JVMs have a JIT built in. Download any of them.
My guess is you are looking for a java to native .exe compiler in the mistaken belief that this will yield a significant performance difference. For Java this is not the case for most real applications and just makes deploying them harder.
Any modern well-performing Java implementation comes with a JIT, and normally you do not have to worry about these kind of things. The most frequent is the Oracle Java implementation available from http://java.com.
If you, however, have a performance problem it is usually a problem with your own code, so use a suitable profiler (jvisualvm in the Sun 6 JDK is a good, free starting point) to identify your bottlenecks, so you can correct them.