What are the advantages of just-in-time compilation versus ahead-of-time compilation?
Question: 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:

  1. **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.
  2. **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.
  3. **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.


Answer:   1. Greater portability: The deliverable (byte-code) stays portable

  2. 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.

  3. 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.

  4. 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.

