Here's another
4-year old comparison that shows JITed
Sun JVM 1.1 is slower, *but* already competitive w/ C++. Page 4 is the table of benchmarks of low-level operations. Note the Java runtime is pre-Hotspot, which is generally considered to be a faster, higher-quality JVM implementation. The "Java is too slow" FUD is really old and worn out. The ancient article Ameesh referenced barely discusses JIT compilers towards the end as a new development.
Here's
another comparison from the same time period that shows similar results. You can check out the
Google query yourself.
Computer programmers have known for decades that interpreted programs are slower than compiled programs, so there's no need to repeat that old line. But guess what, neither Java or C# or VB6 is interpreted. Heck, I think even the scripting language Perl is JITed these days, I think.
So IMHO, I think charrison is simply wrong that Java is slow due to runtime interpretation. It's slower (but often good enough) because the runtime provides extra value that simply costs CPU cycles: bytecode verification, automatic memory management, dynamic code loading, etc. Java is by no means perfect but it's a good choice for many tasks; it also has some flaws that have yet to be ironed out.
Java performance does have some drawbacks (e.g. it's not the right choice for crypto or high-performance math), which I won't detail, but the main one that misleads some people is the JVM load time. Yes, this gives the appearance that application load-up is sluggish, but it does not affect the actual runtime performance. Even in that case, J2ME runs on tiny devices which shows Java is more versatile than many people think.
Lastly, the Java Hotspot VM is actually both JITed, and occasionally interpreted. JIT'ing bytecode is not a free process, so the theory goes that you shouldn't JIT the entire codebase the first time through, but rather you can JIT code on demand. Sun calls this mixed-mode, which contrasts with the CLR that specifies IL *must* be JITed. This is an implementation decision, as some JVMs do always JIT bytecode. Logically, I've read many CS people think the dynamic approach is just as good as the static always JIT approach.