1. CPUs have gotten very good at doing runtime optimization kinds of things on their own, like predicting branches and reducing the cost of virtual function calls. 2. Java only does optimizations that can be done quickly, since the optimizer has to compete with the executing program itself. 3. The claim was overblown to begin with, and Java is trying to do too many other things, like be secure, that interfere with performance.
They use Java because it's fast enough, easy, safe, reliable, easy to instrument, easy to debug, has wonderful tool support, is mature, has many tested and heavily used frameworks, has a free chunk of code to do anything you can imagine you can just snag via maven, integrates with everything, works on all major platforms and costs nothing.
That makes it fast in other ways.
Writing really cache friendly code in Java requires to look at the problem orthogonally and use int[]/long[] instead of a small Object with 3 small ints.
The Java version simply features some quite horrific code but can easily be run in parallel - no one mentions that. Using streams in pure functional way w/o the parallel in mind is a ritual suicide.
Finally, The CPU running benchmark has only 2 cores which is a disadvantage with tons of allocation and garbage.
Converting Object[] arrays into single chunks of packed members when they're all the same type would be a pretty big win by itself.
1) You wrote that code in BOTH Java and C++, optimized both, and compared their running times.
2) Said code was CPU bound. For heavy IO bound code you could even use TCL and get "fractional" differences.
See http://benchmarksgame.alioth.debian.org/u64q/performance.php...
In terms of raw CPU speed, access to vector instructions directly can be game changer in various applications. Also C/C++ compilers are also getting better each day.
That is a very good observation. Looking at back in the past at some point memory speed wasn't that much slower than CPU speed (rather because CPU speeds were not that fast then).
So then throwing more memory at something seems like a very good way improve performance. Like say following long chains of pointers through some nested structure or long linked list was ok. At some point CPU speed went through the roof and left memory access speeds behinds.
So then caches became very important. Cache aware programming was a "thing".
That, coupled with lots having virtualized/cloud machines everywhere that have limited memory kind of turned that initial thinking on its head. Small memory footprint became a desirable trait. Just like in the old MS-DOS & Turbo Pascal days.
Java sort of flourished and grew in that time period where "throw more ram at it to get performance" was a very obvious thing to do. Now I think it is less obvious that is the best way.
(And perhaps Java's current or future GC and JIT strategies will start to take into account caches and memory frugality better).
Now that said I am still amazed at how it can achieve such great performance given all the stuff it does behind the scenes. It is not faster than C but heck, it is very fast still.
Also, the JVM JIT needs a steady-state workload to make good guesses about it's optimizations - if it JITs a bunch of methods and then the load changes such that the optimizations no longer apply (loops iterate differently, inlined methods don't get called as much), the JVM's runtime optimization can be foiled. JITting a very heterogenous program can trick the JVM into finding a local-minimum in native performance (which I guess is still a lot better than actually interpreting java byte code).
I mean, Fortran did worse than Java. Where is your writeup for that?
http://www.artima.com/designtechniques/hotspotP.html
"According to Sun Microsystems, the Hotspot virtual machine, Sun's next-generation Java virtual machine (JVM), promises to make Java "as fast as C++.""
There's not a lot of wiggle room there.
There are plenty of serious, technically deep people trying to convince their colleagues that Java is as fast as C.
Such persons are quite annoying as they try to influence a lot of students.
You'll note that the FORTRAN native code is indeed beaten by Java.
1. Fortran's compilers haven't advanced at the same rate as other languages due to its lack of popularity.
2. Fortran is inherently harder to optimize.
3. People have forgotten how to write fast Fortran, since no one uses it anymore.
I don't know which it might be.
Fortran compilers have been making quite some progress (particularly ifort, but gfortran isn't bad recently).
And due to the way multidimentional arrays are built into the language, aliasing isn't nearly as much of an issue for aggressive optimizations.
next_forests.reserve(forests.size() * possible_meals.size());
helps quite a lot compared to the small header-full instances Java features.I'm instead shocked that the C++ version beat Fortran.
./magic_forest_gcc 617 655 606 7.22s user 0.36s system 100% cpu 7.580 total
./magic_forest_icc 617 655 606 7.00s user 0.34s system 100% cpu 7.340 total
./magic_forest_clang 617 655 606 5.73s user 0.25s system 100% cpu 5.980 total
gcc version 4.8.2
icc version 14.0.1
clang version 3.4
(On 3.14 powered arch linux)
It's might be interesting to see what kind of optimisation clang does, but I currently don't have the time to look into it.Having said that, most of ICC's general gains over GCC and LLVM are due to the much faster maths libraries (even more so on Linux), and that doesn't look like that would be useful for these tests...
clang 29K
gcc 36K
icc 89K