Now compare that C compiler to the jvm compiler, which has the benefit of using detailed information about the exact system configuration and other runtime behaviours during its compilation phases.
Which one has the advantage?
Now compare that C compiler to the jvm compiler, which has the benefit of using detailed information about the exact system configuration and other runtime behaviours during its compilation phases.
Which one has the advantage?
The JVM compiler compiles for the JVM, which is written in C. So, how again can something written in C perform faster than...something written in C?
I'm not claiming that line by line transcription, C will always perform each particular operation faster than Java. But the fact that you could write the entire JVM in C means that you could recreate the exact platform and replicate the results. Is that sane? No, not really.
Comparing languages is typically silly, as it mostly boils down to implementation. If you -really- intend to compare speeds of languages, it would necessitate writing the best possible code in both languages, which may or may not even resemble each other. Under those circumstances, Java is not capable of beating C. Ever.
I don't understand why this is an argument anymore, it doesn't really even make much sense...unless my definition of 'language speed' is unusual.
Because the eventual target is native code, the only limit on performance[2] is what program transformations the compiler is willing to perform. This is limited by how much information the compiler has, and what sort of transformations are valid in the language.
For the first, it's about a wash. Java has a mix of 'safety' features that may obligate inserting checks at runtime that C would assume away, but it also forbids a lot of things that a C compiler would have to accept that limit the ability to optimize programs. In particular, a C compiler has to make a lot of pessimistic assumptions about what all those pointers are doing and what happens to memory across an external function call.
JVMs have a solid advantage in the second -- it performs the equivalent of profile guided optimization at runtime against real usage patterns, something that AFAIK no C compiler even attempts... and the runtime tooling needed to turn C into something you could JIT-optimize would result in something I don't think most C programmers would recognize.
A third issue is GC, which is on by default in Java-land and off by default in C: if your program is under very little memory stress and has very complex memory access patterns, the overhead of malloc()/free() is going to be huge compared to the cost of running the occasional GC. But, if your program is under strong memory stress and the logic to determine when to malloc() and when to free() is trivial, GC overhead will be a serious issue.
None of this means a given Java environment is faster than a given C environment but there's not really anything you could assume from first principles that makes one faster than the other. Neither reaches the ultimate "speed of light" of computation that is self-modifying hand-tuned machine code favored by all Real Programmers[3].
But the real bottom line for performance is which language has faster library implementations, and which has idioms that programmers actually use that produce faster or slower code. Those considerations are probably going to be way more important than the hypothetical top speed of a perfect program made by cycle-counting weenies. It's also the sort of thing you'd have to run actual experiments at large scale to answer.
[1] the JVM might interpret Java bytecode that isn't frequently run based on some optimization heuristic, but it doesn't have to. A 100% JIT emitting JVM could exist, and might even be a JVM flag for all I know.
[2] if you ignore the time JVM spends optimizing at load/JIT time, which you can in most cases aside from startup time.
[3] http://www.catb.org/jargon/html/story-of-mel.html
[4] Despite this extensive apology for Java, I despise it and if I never have to touch it or the JVM ecosystem again it will be too soon.
Well, first of all, the JVM generates machine code, not C.
Apart from that, you can easily be shown to be wrong. If you are compiling a binary with C, you are compiling for the lowest common denominator. Say, if you are compiling for x86_64, you are probably compiling for all x86_64 CPUs. You can optimize for newer instances of x86_64 (say Core i3), but you cannot use any instructions that are not available on e.g. Core 2, if that is the lowest common denominator that you support.
The Java VM could, on the other hand, decide to use instructions during the compilation of hot spots which are available on a Core i3 and not on a Core 2, when it detects that the CPU is a Core i3.
This is absurd.
First of all, there isn't one JVM. There are dozens to chose from, many of them certified. Each implemented in whatever language their designers have chosen.
Some JVMs are meta-circular, meaning they are also written in Java. For example, Squawk, Maxime, Jikes RVM.
Second, even if you mean Oracle's JVM, the embedded version is not the same as the desktop/server one, one uses C the other C++.
Not to mention that after Java 8's release, Hotspot might be replaced by Graal, the new JIT compiler written in Java as well.
Currently being developed and already in use by AMD for their Java/GPGPU work.
Easy. JVM has runtime information it can use that C compiler simply doesn't have. There are some synthetic benchmarks that show how "java is faster than C".
Even that assumes that your program does not significantly shift its behavior mid-execution--in fact, you're optimizing for the average, not the current case.
One of the coolest JIT things is ability to inline virtual calls. Think about that, I could have my code calling a 3rd party library calling another 3rd party library thru 10 levels of stack and if all that call ever returns is "false", then JIT will optimize right through all that.
I don't believe PGO does virtual call inlining. That's a C++ nonstarter. In C, the equivalent would be inlining for function pointer calls.