Interpreter, JIT Compiler and "Offline" Compiler
Difference between a JIT compiler and an
interpreter
To keep it simple, let's just say that an interpreter will run the bytecode (intermediate code/language). When the VM/interpreter decides it is better to do so, the JIT compilation mechanism will translate that same bytecode into native code targetted for the hardware in question, with focus on the type of optimizations requested.
So basically a JIT might produce a
faster executable but take way longer
to compile?
I think what you are missing is that the JIT compilation happens at runtime and not compile time (unlike an "offline" compiler)
JIT Compilation has overhead
Compiling code is not free, takes time also. If it invests time on compiling it and then goes to run it only a few times, it might not have made a good trade. So the VM still has to decide what to define as a "hot spot" and JIT-compile it.
Allow me to give examples on the Java virtual machine (JVM):
The JVM can take switches with which you can define the threshold after which the code will be JIT compiled. -XX:CompileThreshold=10000
To illustrate the cost of the JIT compilation time, suppose you set that threshold to 20, and have a piece of code that needs to run 21 times. What happens is after it runs 20 times, the VM will now invest some time into JIT compiling it. Now you have native code from the JIT compilation, but it will only run for one more time (the 21), which may not have brought any performance boost to make up for the JIT process.
I hope this illustrates it.
Here is a JVM switch that shows the time spent on JIT compilation -XX:-CITime
"Prints time spent in JIT Compiler"
Side Note: I don't think it's a "big deal", just something I wanted to point out since you brought up the question.