Q: "Isn't a program running on a virtual machine slower than a native-code program, because the JVM program has to constantly decode the bytecodes?"
A: Not necessarily, in theory. Of course, a totally naive implementation, like the following pseudocode:
byte[] bytecodeArray = readClassFile(); while (!shouldHalt()) { Instruction current = getNextInstruction( bytecodeArray ); current.execute(); }
would be dog slow. However, a good JVM works nothing like this. Among other things, it will use a just-in-time compiler, or JIT. Unlike the Java front-end compiler (javac), the JIT:
Hence, once the initial cost of loading and JIT-compiling the bytecode is done, the code can theoretically run as fast as (or faster than) code that was natively compiled ahead of time. Given a wizardly JVM, Java will run at speeds equal to native code.
In practice, the following constraints currently make JIT-compiled code, all else being equal, run slightly slower than code from a good native-code compiler for, e.g., C++:
Making Java code run fast, and making JITs effective, is a major area of current research.
By the way, take Java vs. C++ benchmarks with a grain of salt. Benchmarks cannot separate performance loss due to JVM overhead from performance loss due to the following features: