Re: C++ Speed Vs. Java
Thomas Richter wrote:
Ivan Novick wrote:
What I am looking for is not really specific measurements or anecdotal
stories from individual people's experience or tastes, or a useless
flame war.
The question is directed to people who know the internal workings of C++
compilation vs. JVM implementation as to empirically is it possible for
Java to execute as fast as C++ and if not by what margin could we expect
the difference to be, a small percentage or an order of magnitude.
And the answer is, as always, "it depends on what you're doing".
What's good on the java side (speedwise, at least) is that objects
are by default passed around as pointers, not as copies, but the same
can be arranged within C++ as well, it just requires a different
programming style.
And without garbage collection, you still have added overhead
(especially in a multithreaded environment) to ensure that the
object eventually gets deleted. It's not accidental that people
trying to show off the performance advantages of garbage
collection tend to use multithreaded programs with lots of
strings and substrings:-).
On the other hand, what's bad on the Java side (speedwise, at
least), is that you have to pass even the simplest types as
pointers, with an additional dereference to access them. If
you've something like:
struct Point { double x ; double y ; /* ctor, etc.* / } ;
the equivalent of:
std::vector< Point > array( 1000000, Point( 1.0, 2.0 ) ) ;
is going to take a lot more time in Java; accessing the elements
of the points in the array may also be slower, because of the
added indirection, and locality is very definitly going to be
significantly worse. (Of course, possible aliasing may cause
the C++ compiler to loose much of that advantage.)
The fact that objects must be dynamically allocated, and that
variables are pointers, and not the actual object, is probably
the biggest thing Java has going against it (from a performance
point of view, certainly---many of us would also argue that it
is a bad decision from a purely software engineering point of
view:-)).
What's also good on the java side is that the JIT can
adjust itself to the usage pattern of a specific method and thus
optimize it right away to the problem domain, but for C++ advanced
compilers (i.e. the intel icc compiler) also offer this type of feedback
optimization, but you are required to feed them with "typical" data.
And a typical error is to give them data from your test suites.
Test suites that go out of their way to exercise all of the
paths, especially those that don't get exercised in typical use.
Barring that, you still have the problem that "typical" data may
vary from one site to the next.
What's bad on the java side (speedwise, again, not conceptionally) is
that a couple of runtime checks are made at runtime, i.e. array
out-of-bounds accesses, and type-checks. It has been argued that a
sufficiently smart JIT compiler can eliminate those.
There have been actual studies concerning the out-of-bounds
checks, not for Java, but for other languages, like Pascal.
Even using very dated optimization techniques, a good compiler
can eliminate well over 90% of them (including all of them in
cricital loops).
It's probably harder to eliminate the type checks, but I've not
seen any actual studies concerning them. Also important is the
fact that the type check that you don't eliminate is a lot more
expensive than any bounds check. Formally, of course, the Java
type system is even stricter than that of C++, and you can write
Java code which never needs a type check. That's not the way
actual Java is written, however.
And, whether any of these effects are dominant in your problem domain is
of course a question you can only answer by experimenting on realistic
data.
My personal problem domain is image procession, and this requires a lot
of data-shuffling and signal processing. Array bounds checking in java
(despite all claims of JIT optimizations) cause a slowdown here by about
a factor of two to three (no kidding), at least for java 1.4 back when I
checked it. You might get different figures nowadays.
I would imagine that aliasing would make C++ optimizers much
less efficient than Java for this sort of application. Unless,
of course, your arrays are of Pixel { int red, blue, green ; },
or something like that. In which case, it's likely that the
slowdown is due to the extra indirections and allocations, and
the loss of locality, rather than bounds checking.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientie objet/
Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]