Java's performance far better that optimized C++

M

Mark A. Gibbs

Gernot said:
Well, how about:

long a, b, double c;
memcpy(&c, a, 4); memcpy(&c+4, b, 4);

or:

template <class T> T& min(T &tParam1, T &tParam2) ...

or:
#ifndef DONT_WANT_THIS
gagagugu
#endif

sorry dude, i think you blew it on all three counts. java _can_
technically do both of the first two things, albeit not as efficiently
as c++. especially java generics (which they are very careful not to
call templates, because they are not really). when you create the java
equivalent of template <typename T> class vector, it actually generates
a vector of Object's (that is, a vector of java.lang.Object objects),
and at runtime silently converts whatever you pass it - even integral
types such as int (!) to and from polymorphic descendants of Object.
thus it appears to be a template type, when in reality, it's just a
vector of base class pointers with methods that return and accept only
objects of type T (and its descendents).

as for the last, the java language specification allows the compiler to
strip dead code:

if (false)
{
// this whole block is stripped
}

i cannot recall whether this is common behaviour or required behaviour,
but i believe it is required. thus, you get hackish conditional compilation.

what's really odd is the recently added assert statement. you heard me:
assert STATEMENT.

you use an assert like this:

assert some_test();

or you can specify a message:

assert some_test() : "Message on assertion fail";

on an assertion failure, an exception is thrown. you can theoretically
catch that exception, handle it, and keep on chugging.

what's even weirder is that assertions are not compiled away in a
"release" build. you compile one way every time, and enable or disable
assertions through a command line switch to the vm.

what that means is that an assertion statement actually contains a
runtime check to see if assertions are enabled. if they are, then the
test is run. in other words:

assert some_test() : "Message on assertion fail";

is actually:

if (assertions_enabled_)
{
if (some_test())
{
throw new AssertionError("Message on assertion fail");
}
}

so even if assertions are disabled, there is a performance penalty to
using them. even if the surrounding block is never entered, you pay the
memory cost. and this is a bloody assert.

tell me again that java is faster than c++ ^_^

indi
 
J

josh

Dario said:
The "Church Thesis" or "Turing-machine-computable" or ...
... means anything to you?

That doesn't apply.

I could design a turing-complete language with no IO. Sure, you can
calculate anything, but no matter what you try, you can't print the result.

-josh
 
V

valentin tihomirov

If you don't like it, don't use it.

Not so simply. Please take a note, the dictatorship means that everyone must
use them. Speaking shortly, we get many people convinced these are the best
langs and it is not possible to escape the loop.
 
R

Rainer Hausbach

Every program you can write in C or C++ may be written
in any other-language that can emulate a Turing-machine
(Cobol, Fortran, APL, PL/!, Algol, Ada, Pascal, Java, C#, etc...).

ACK.

but I was refering to special task like an Operating System (Loader,
Kernel!), device driver etc.
Java as an interpreted language IMHO lacks some needed features here.

Rainer
 
D

Dietmar Kuehl

What is the flaw in this benchmark, other than not unrolling loops
(which is probably a big flaw)?

I haven't looked to closely at the source code but eg. in "sieve.cpp" the
program is not correct: it causes undefined behavior because an iterator
for a vector is placed beyond the end of the vector (further than the
past the end iterator). No big deal since it will normally work on
typical platforms but I'd think the programs should be correct.
But I think the results are still startling, considering that
Java is interpreted.

It is a misconception that Java is interpreted: it is not. Java is a
compiled language. The major difference to C++ (if you leave out
Microsoft's C++ for .Net) is that it uses some form of platform
independent assembler which is transformed into a platform's native
assembler at run-time (when it is loaded and possible later again when
hotspot optimization is done). The major differences between Java and
C++ are in their respective object models, not that one is compiled and
the other is not. And most of the benchmarks stay clear of the object
model differences operating on the low-level built-in types like 'int'
where the object models are identical. One of the examples where there
is a difference in the object model (methcall.*) the test forces the
Java model on the C++ code while making sure that a Java specific
optimization can and will kick in.
Maybe the fault is with g++'s optimization.

The gcc optimizations are apparently not as good as those of other C++
compilers owing to the needs and history of gcc. However, most of
these objective benchmarks are designed to get a false impression - and
even fail to do so when using more appropriate optimization flags.
This is not a valid way of benchmarking. To compare the performance,
you need to test the same algorithm coded in both languages.

This is interesting... I would guess that good functional languages will
optimize eg. the Fibonacci example to effectively avoid the recursion:
although the source looks like the same algorithm is used, the system
effectively does very different things. Is this a valid way of
benchmarking? I could easily contrive a set of benchmarks relying heavily
on recursion most functional programming language would win. Does this
benchmark tell me anything about using the languages for problems for
algorithms which are inherently non-recursive (of course, they can be
formulated recursively but the optimizations I used to win the benchmarks
do not kick in)?
You can't code a logarithmic time algorithm in C++ and an
exponential-time one in Java for the same problem and use the results
to claim that C++ is faster.

If the only thing the Java programmers are up to is an exponential-time
algorithm while the C++ people can come up with a logarithmic one, I
think this is a pretty reasonable approach! The point is, that people
comfortable in a language should do the best they can for the respective
benchmark. If the algorithms turn out to have different complexities
this might expose flaws in the respective languages and this is exactly
what benchmarks are about: to expose flaws. It is not the point of
benchmarks to tune them to let something particular look good. ... and
other benchmarks don't make any assumption about algorithms. For example,
a typical database benchmark tosses a set of SQL statements at a data
base and determines what it takes to process them. Is this unfair because
some database uses inferior algorithms and thus the others should be
disqualified? The point about the Fibonacci example was not that C++ is
much faster using this other algorithm. The point was that nobody would
implement this computation the way it was done in the first place -
except in a functional language where it is a rather sensible approach
to do.
You would have to
compare the above code with the *same* algorithm, coded in Java.

I don't think so. Substitute "*same*" by "*best*" and we agree.
The
algorithm used in the benchmarks is well-known to be a particularly
bad one for generating Fibonacci numbers, but the point is moot. In
the benchmark, you have to test the same algorithm in both languages,
not a fast algorithm coded in C++ against a slow one coded in Java.

Do you want me to design a few benchmarks particularily suitable for C++
which nobody in their right mind would implement that way in Java?

One of the things this "benchmark" highlights is that the developers for
other languages are working on improving the performance. I think this
should also apply to C++. Especially in the area of the standard C++
library I'm aware of a large potential for improvements. Eg. the fastest
version of the wc-benchmark I could come up with is only fast with my
own implementation of the standard C++ library where for_each() takes
advantage of the "segmented sequence optimization" and this code is not
[yet] available publically (I don't have the resources to finish up this
stuff...).
 
V

valentin tihomirov

I've heard such silly statements only from narrow-minded C/C++ programmers.

That's not really true. It's true that an algorithm that can be
implemented in one Turing complete language can also be implemented in
any other Turing complete language. Implementing an algorithm,
however, is somewhat different from implementing a complete program or
(as was mentioned earlier) something like an OS.
You don't make sense here. C++/Java are not the best candidates for
real-time programming indeed. But real-time system and OS are different
notions. Any program can be accomplished using memory-access only (ports and
special machine instructions are rate). What is the definition of "complete
program"?


int *screen = (int *)0xb80000;

will give you direct access to the machine's text-mode screen buffer.
It's not portable, but for the target hardware it works perfectly
well.
Java doesn't allow things like that. Direct access to the hardware
isn't portable in C or C++, but Java simply doesn't allow it at all.
I was asked not to call you C programmers but this is C code. It will fail
executing on a modern OS.
Any byte-array acces in java is a subject of boundry check indeed. However,
a cgi dll attached to a WEB sever is located in its address space. The
option for unlimited memory access, enabes your to fail the server
(unintentionally). As a designer, I will choose a tool that allows me to
accomplish faster (C/C++ compilers are slow, stupid and produce code often
slower than say Delphi compiler). Java sandbox targets reliable modules
which cannot distroy the rest of the system. Furthermore, Java allows for
exceptions which when not handeled show you a sensible error message with
the line of source code caused the error. Which is not possible in the case
of unlimited memory access (you get mem access violation dialog, don't
you?). These consiferations are often more preferred over direct memory
access in the modern SW design, espesially enterprise programming.



So, my point is that C/C++ programmers are convinced they are best operating
on pointers. What is a problem to write that line of code in, say Pascal?
TurboPascal even defines a special word for accessing abolute mem locations:
var screen: array[0..N] of byte absolute $A000:$C000;


Finally, ANY memory access (say assigning a variable) is direct memory
access. Furthermore, don't you know about java HW processors? How will you
access HW in a Java-bytecodes-only system?
Real-time Low-power Java Processor aJ-100
http://www.systronix.com/jstamp/reality.htm


In the end, there's another major problem: Java is defined as more
than a language. Even if you accept source code that's syntactically
identical to Java's, if you compile it directly to native machine code
(other than for a Java machine) what you have isn't Java anymore.
This means that attempting to implement a Java Virtual Machine in Java
leads directly to infinite recursion -- to work, it HAS to be written
in something else.
So, what is your point? Yes, Java is not only just a lang, it is a platform.
How do you implement a platform for C/C++ in these langs? I whould implement
HW in VHDL. Anyway, I can generate HW netlists in Java (manufacturing still
should be done on a factory).



So, stop blaming java, it is much more effective for modern
desktop/enterpricse programming that C/C++. I would still prefer
structural/functional c/pascal to asm/oop writing for real-time tiny micros.
 
R

Rob Williscroft

Mark A. Gibbs wrote in @twister01.bloor.is.net.cable.rogers.com in comp.lang.c++:
assert some_test() : "Message on assertion fail";

is actually:

if (assertions_enabled_)
{
if (some_test())
{
throw new AssertionError("Message on assertion fail");
}
}

Why, when loading the class without asserts enabled can't the loader
just strip the whole thing ?. (rhetorical - of course it can).

Indeed (since were in c.l.c++) can't a C++ compiler compile to the
the java vm (I'm told its turing complete :) and #define assert( x )
as:

#define assert( x ) emit( "assert (%b) : \" #x "\";", x )

Not a fan of java BTW, just bored with this whole nonsense thread.

Rob.
 
T

tom_usenet

What is the flaw in this benchmark, other than not unrolling loops
(which is probably a big flaw)?

Just that the tested code is generally not idiomatic. What's the point
of testing how fast some code is that no one in their right mind would
write?
Yes, -O2 doesn't unroll loops (-O3 doesn't either). The benchmarks
would have been more interesting if the -funroll-loops option was
used. But I think the results are still startling, considering that
Java is interpreted. Maybe the fault is with g++'s optimization.

Part of the fault. I could produce a comparison of VC7.1 and GCC on a
couple of them, just to see.
This is not a valid way of benchmarking. To compare the performance,
you need to test the same algorithm coded in both languages. You
can't code a logarithmic time algorithm in C++ and an exponential-time
one in Java for the same problem and use the results to claim that C++
is faster.

No, I agree, but that's not what I suggested. Instead, you'd code
idiomatically for the language in question. You probably would use the
recursive algorithm in a functional programming language that knows
how to optimize it to linear time. However, that's not how C++ or Java
programmers would do it, so what's the point to testing how long it
takes to run?
compare the above code with the *same* algorithm, coded in Java. The
algorithm used in the benchmarks is well-known to be a particularly
bad one for generating Fibonacci numbers, but the point is moot.

Yes the point is moot - seeing how fast bad algorithms run is of no
interest to me.

Tom
 
D

Dietmar Kuehl

[author of this quote remove to protect the innocent...]

That would be a stretch! A Turing-machine is in its minimal form an
infinite tape on which the machine can write zeros and ones plus a
state machine. In each step the machine can write, read, or move the
tape and make a state transistion. To my knowledge, no CPU works that
way and in any case, none of them has an infinite tape.
Every program you can write in C or C++ may be written
in any other-language that can emulate a Turing-machine
(Cobol, Fortran, APL, PL/!, Algol, Ada, Pascal, Java, C#, etc...).

Actually, this is not the statement of the being Turing-computable. The
statements about Turing-machines are about computability: whatever you
can compute using a Turing-complete device, you can also compute with
any other Turing-complete device. Programming languages supporting a
fairly small set of operations (assignment, condition evaluation, and
counting) are Turing-complete (assuming they can address and use an
infinite amount of memory but this is a marginal detail which is normally
ignored).

This does not address in any way certain practical problems like how to
talk to some hardware device. Although all of the above programming
languages are Turing-complete, not all of them are capable of [without
extensions] to access hardware directly as is necessary for writing an
operating system.
 
D

Dietmar Kuehl

tom_usenet said:
Modular languages do make writing good IDEs for them much easier. Java
has other problems though, of course, mostly memory usage, start-up
time and performance related.

Actually, the major omission from Java (and .Net) is, IMO, support for
Generic Programming, i.e. data structure independent implementation of
algorithms with the performance of data structure dependent equivalents.
Java's generics are not at all up to something like this (Java generics
are more in the ballpark of avoiding certain casts). Once the community
at large got over the data shuffling class of programs we are currently
mostly using, the community will recognize the need for a generic
approach to implement algorithms.
 
J

Julie

Victor said:
X-No-archive: yes


Applying well known tactics of incomplete quotes, eh?

Not this sub/super set topic of C/C++ again...

Let's face it, for some it is easier to consider C++ a (loose) superset of C,
even though it isn't (although it *once was*) a well-defined 100% superset.

For others, well, I don't know what they call C++ in relation to C, and yes,
there is a well-defined relationship between the two.

Too bad there isn't a term for a superset that encompasses 95+%... Well,
unless someone has a better suggestion, I'm proposing that C++ be called a
'colloquial superset' of C, if the C/C++ set relationship is being discussed.

So:

- C++ is not a mathematical superset of C.

- C++ is a colloquial superset of C.

- Bjarne's discussion on the set/superset nature of C++ in the quote
referenced above is incomplete, unclear, and subject to dissension because of
the strict interpretation of the (implied mathematical) definition of a set.
 
V

valentin tihomirov

Actually, the major omission from Java (and .Net) is, IMO, support for
Generic Programming, i.e. data structure independent implementation of
algorithms with the performance of data structure dependent equivalents.
Java's generics are not at all up to something like this (Java generics
are more in the ballpark of avoiding certain casts).

Actually, generics avoid run-time problem (the casts) at compilation time.
 
D

Default User

Julie said:
Let's face it, for some it is easier to consider C++ a (loose) superset of C,
even though it isn't (although it *once was*) a well-defined 100% superset.


When was this?



Brian Rodenborn
 
V

valentin tihomirov

This does not address in any way certain practical problems like how to
talk to some hardware device. Although all of the above programming
languages are Turing-complete, not all of them are capable of [without
extensions] to access hardware directly as is necessary for writing an
operating system.

Have you read this message Message-ID: <[email protected]>
http://groups.google.com/groups?q="...F-8&[email protected]&rnum=1
in this thread?

Which HW access do you need? If you think a little, you'll come to
surprising conclusion, any high-level language specifies the single and only
way to assess HW: MEMORY READS and WRITES. Which of the langs above do not
belong this category?
 
D

Dietmar Kuehl

valentin said:
Actually, generics avoid run-time problem (the casts) at compilation time.

Yes. The problem is that this is roughly the only thing they do, ie. they
are pretty useless for more advanced generic programming. They remove the
need for casts when using containers. Big deal... They do not support
algorithms on arbitrary containers. Have a look at the algorithms in the
standard C++ library to get an idea what I'm talking off. For a more
intriguing example, have a look at the Boost Graph Library (see
<http://www.boost.org/>). Stuff like this is impossible on the basis of
Java generics.
 
M

Mark A. Gibbs

Rob said:
Mark A. Gibbs wrote in @twister01.bloor.is.net.cable.rogers.com in comp.lang.c++:




Why, when loading the class without asserts enabled can't the loader
just strip the whole thing ?. (rhetorical - of course it can).

possibly. depends on what the java "standard" says about toggling
asserts at run time. but even if it does, that means the .class loader
has another processing step, so you still pay for your unused asserts in
java.

i'm surprised no one jumped at the part i find most ironic:

assert there_is_enough_memory_to_allocate_another_class();

// becomes ------>

if (assertions_enabled_)
{
if (!there_is_enough_memory_to_allocate_another_class())
{
throw new AssertionError("Message on assertion fail");
// ^^^
}
}

mark
 
D

Dietmar Kuehl

valentin said:
This does not address in any way certain practical problems like how to
talk to some hardware device. Although all of the above programming
languages are Turing-complete, not all of them are capable of [without
extensions] to access hardware directly as is necessary for writing an
operating system.

Have you read this message Message-ID: <[email protected]>
http://groups.google.com/groups?q="...F-8&[email protected]&rnum=1
in this thread?

It misses the point entirely. Instead of accusing C++ programmers of being
narrow minded, I'd suggest that you check your assumptions. Also note, that
all I said was that Turing completeness does not make a statement about
able to do all the practical things involved in creating a real program
like an operating system. It merely makes a statement about what kind of
problems can be solved with a computing device operating on some idealized
machine: a Turing machine has no operating system. The programs on this
machine are there and run. There is no statement whatsoever how they come
there. Turning machines also have not concept of input or output although,
in some sense, you can assume input and output to be the contents of a tape.
This is sufficient for an idealized, theoretical view for which you can
proof certain computability things. It does not, however, address practical
issues of real programs.
Which HW access do you need? If you think a little, you'll come to
surprising conclusion, any high-level language specifies the single and
only way to assess HW: MEMORY READS and WRITES. Which of the langs above
do not belong this category?

This is a purely theoretical point of view: yes, in theory you are right.
In theory, practice and theory are the same - in practice they are not. It
is up to the last point your "little thinking" holds up. At this last step
it fails. ... but then, maybe it is just me:

I have failed to notice the approach how to access memory at a specific
location, eg. 0x80000 (absolute, not memory mapped address) on an x86 based
system, with Java. I'm sure there are Java extensions which may allow things
like this (JNI is one of the approaches - going through C or C++...). The
last Java specification I looked at didn't include things like this apart
from JNI (of course, in this sense Linux is an operating system written in
Java: it just happens that it only uses JNI code and therefore even omits
the JNI part :)

Sure enough, on a hardware which effectively implements [a reasonable
subset of] the Java platform, some programming language creating Java byte
code, eg. Java, is about the only choice to create an operating system.
However, I'd like to see an implementation of an operating system for my
x86 machine entirely written in Java. There are definitely operating systems
written in C for this platform (eg. Linux and Free BSD) and, AFAIK also at
least one written in C++ (Windows; it uses either C or C++ but I'm not sure
that it really uses C++). I'm unaware of an operating system written in
Java. Of course, following your general logic, Java seems to be the obvious
choice when embarking on the quest to create an operating system. Strangely
then that there is none...

BTW, personally I don't care about the possibility to write an operating
system in a particular language, mainly because my day to day tasks don't
include writing operating systems. I'm also not too concerned about using
the most efficient programming language (after all, I'm using C# and Java
for certain tasks - sorry, I couldn't resist (*)). To me the reason for
using C++ is that I can express things I cannot express in the same
idiomatic and concise way in any other programming language I'm aware of (of
course, the language also has to be practical in the sense of being
relatively widely available and sufficiently efficient). I wouldn't consider
C++ ideal (for example I would prefer a simpler and possibly more concise
notation for certain things, especially templates) but it is my preference
from all languages I'm fluent with (which includes Java among others).

(*) Before you ask: I'm using Java if I need a platform independent GUI. It
is a pain due to the difference between different JVMs but it is a
better alternative than using C++ as there is even less than in Java
such a thing as portable platform library.
 
D

Dietmar Kuehl

Julie said:
Too bad there isn't a term for a superset that encompasses 95+%... Well,
unless someone has a better suggestion, I'm proposing that C++ be called a
'colloquial superset' of C, if the C/C++ set relationship is being
discussed.

So:

- C++ is not a mathematical superset of C.

- C++ is a colloquial superset of C.

- Bjarne's discussion on the set/superset nature of C++ in the quote
referenced above is incomplete, unclear, and subject to dissension because
of the strict interpretation of the (implied mathematical) definition of a
set.

Although I personally don't mind the view of C++ being a superset of C
(after all, there is effectively a pretty straight-forward approach to
turn any legal C program into a legal C++ program - essentially rename
all identifiers in the C program which happen to be C++ keywords; this
still does not address everything but almost), I want to point out the
the origin of this subthread, the claim that C++ programmers are just C
programmers, is still false:

- A C++ programmer does not need to know C because there are other
subsets of C++ which are sufficient to program effectively with C++
than just the C subset.
- The idioms used in C++ are rather different from the C idioms or,
formulated differently, C++ is an entirely different culture.

That said, I have to admit that there is huge a fraction of people using
C++ as something I would call "extended C", eg. MFC is an example of this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top