Bear in mind that the following is only comparing the difference between native and JIT compilation, and doesn't cover the specifics of any particular language or frameworks. There might be legitimate reasons to choose a particular platform beyond this.

When we claim that native code is quicker, we are talking about the typical use case of natively compiled code versus JIT compiled code, where the typical use of a JIT compiled application is to be run by the user, with immediate results (eg, no waiting on compiler first). In that case, I don't think anyone can claim with a straight face, that JIT compiled code can match or beat native code.

Let's assume we have a program written in some language X, and we can compile it with a native compiler, and again with a JIT compiler. Each work flow has the same stages involved, which can be generalized as (Code -> Intermediate Representation -> Machine Code -> Execution). The big difference between to two is which stages are seen by the user and which are seen by the programmer. With native compilation, the programmer sees all but the execution stage, but with the JIT solution, the compilation to machine code is seen by the user, in addition to execution.

The claim that A is faster than B is referring to the time taken for the program to run, as seen by the user. If we assume that both pieces of code perform identically in the Execution stage, we must assume that the JIT work flow is slower to the user, as he must also see the time T of the compilation to machine code, where T > 0. So, for any possibility of the JIT work flow to perform the same as the native work flow, to the user, we must decrease the time of Execution of the code, such that Execution + Compilation to machine code, are lower than only the Execution stage of the native work flow. This means we must optimize the code better in the JIT compilation than in the native compilation.

This however, is rather infeasible, since to perform the necessary optimizations to speed up Execution, we must spend more time in the compiling to machine code stage, and thus, any time we save as a result of the optimized code is actually lost, as we add it to the compilation. In other words, the "slowness" of a JIT based solution is not merely because of added time for the JIT compilation, but the code produced by that compilation performs slower than a native solution.

I'll use an example: Register allocation. Since memory access is some thousands of times slower than register access, we ideally want to use registers wherever possible and have as few memory accesses as we can, but we have a limited number of registers, and we must spill state into memory when we need a register. If we use a register allocation algorithm which takes 200ms to compute, and as a result we save 2ms of execution time - we're not making the best use of time for a JIT compiler. Solutions like Chaitin's algorithm, which can produce highly optimized code are unsuitable.

The role of the JIT compiler is to strike the best balance between compilation time and quality of produced code, however, with a large bias on fast compilation time, since you don't want to leave the user waiting. The performance of the code being executed is slower in the JIT case, as the native compiler is not bound (much) by time in optimising code, so is free to use the best algorithms. The possibility that overall compilation+execution for a JIT compiler can beat only execution time for natively compiled code is effectively 0.

But our VMs are not merely limited to JIT compilation. They employ Ahead-of-time compilation techniques, caching, hot swapping, and adaptive optimizations. So let's modify our claim that the performance is what the user sees, and limit it to the time taken for execution of the program (assume we've AOT compiled). We can effectively make the executing code equivalent to the native compiler (or perhaps better?). A big claim for VMs is that they may be able to produce better quality code then a native compiler, because it has access to more information - that of the running process, such as how often a certain function may be executed. The VM can then apply adaptive optimizations to the most essential code via hot swapping.

There's a problem with this argument though - it assumes that profile-guided optimization and the like is something unique to VMs, which is not true. We can apply it to native compilation too - by compiling our application with profiling enabled, recording the information, and then recompile the application with that profile. It's probably also worth pointing out that code hot swapping is not something that only a JIT compiler can do either, we can do it for native code - although the JIT based solutions for doing this are more readily available, and much easier on the developer. So the big question is: Can a VM offer us some information that native compilation cannot, which can boost the performance of our code?

I can't see it myself. We can apply most of the techniques of a typical VM to native code too - although the process is more involved. Similarly, we can apply any optimizations of a native compiler back to a VM which uses AOT compilation or adaptive optimizations. The reality is that the difference between natively run code, and that run in a VM is not as big as we've been made to believe. They ultimately lead to the same result, but they take a different approach to get there. The VM uses an iterative approach to produce optimized code, where the native compiler expects it from the start (and can be improved with an iterative approach).

A C++ programmer might argue that he needs the optimizations from the get-go, and shouldn't be waiting for a VM to figure out how to do them, if at all. This is probably a valid point with our current technology though, as the current level of optimizations in our VMs is inferior to what native compilers can offer - but that may not always be the case if the AOT solutions in our VMs improve, etc.