Java is slower than C++!

S

Stefan Ram

Hotspot is being given Bytecode, which is as good as source code.
Hotspot then translates this to the language of the hardware
processor.

Therefore, a code segment, that does not allocate or release
memory and does not call other methods, but only does double-
and int-arithmetics, loops and branches should be compiled to
machine code similar to the one created by a C++ compiler.

Thus, it should be approximately as fast as the C++ code (or
even faster, because Hotspot knows more about the runtime
environment than the C++ compiler does).

So why is the Java program in the following benchmark still
slower than the C++ program?

(Most of the runtime is spent in the first function / method
that does not call other functions / methods nor does memory
allocations / deallocations.)

#include <stdio.h>
#include "windows.h"

#define BAILOUT 16
#define MAX_ITERATIONS 1000

int mandelbrot( double const x, double const y )
{ double cr = y - 0.5;
double zi = 0.0;
double zr = 0.0;
int i = 0;
while( 1 )
{ ++i;
double const temp = zr * zi;
double const zr2 = zr * zr;
double const zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + x;
if( zi2 + zr2 > BAILOUT )return i;
if( i > MAX_ITERATIONS )return 0; }}

void main1()
{ char * p =( char * )malloc( 82 * 82 + 82 );
if( p )
{ char * q = p;
for( int y = -39; y < 39; ++y )
{ *q++ = '\n';
for( int x = -39; x < 39; ++x )
*q++ = mandelbrot( x / 40.0, y / 40.0 )? ' ' : '*'; }
*q++ = 0;
// puts( p );
free(( void * )p ); }}

int main()
{ for( int i = 0; i < 20; ++i )
{ long const start =( long )GetTickCount();
main1();
printf( "%ld ms\n",( long )GetTickCount() - start ); }
system( "PAUSE" ); }


154 ms
149 ms
148 ms
149 ms
147 ms
147 ms
147 ms
146 ms
146 ms
146 ms
145 ms
150 ms
145 ms
145 ms
146 ms
145 ms
150 ms
148 ms
149 ms
148 ms

public class Main
{ final static int BAILOUT = 16;
final static int MAX_ITERATIONS = 1000;

public static int iterate( final double x, final double y )
{ final double cr = y - 0.5;
double zi = 0.0;
double zr = 0.0;
int i = 0;
while( true )
{ ++i;
final double temp = zr * zi;
final double zr2 = zr * zr;
final double zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + x;
if( zi2 + zr2 > BAILOUT )return i;
if( i > MAX_ITERATIONS )return 0; }}

public static void main1()
{ final char[] sb = new char[ 82 * 82 + 82 ];
int q = 0;
for( int y = -39; y < 39; ++y )
{ sb[ q++ ]= '\n';
for( int x = -39; x < 39; ++x )
sb[ q++ ]= iterate( x / 40.0, y / 40.0 )== 0 ? '*' : ' '; }
/* java.lang.System.out.println( new java.lang.String( sb )); */ }

public static void main( final java.lang.String[] args )
{ for( int i = 0; i < 20; ++i )
{ final long a = System.nanoTime();
main1();
final long dt = System.nanoTime() - a;
java.lang.System.out.println(( dt / 1000 / 1000 )+ " ms" ); }}}


358 ms
220 ms
279 ms
214 ms
215 ms
214 ms
215 ms
214 ms
215 ms
215 ms
215 ms
214 ms
215 ms
214 ms
215 ms
214 ms
236 ms
214 ms
216 ms
214 ms

C++ 6,75 main1/s
********************************************************************

Java 4,67 main1/s
***********************************************

Based on code from

http://www.timestretch.com/FractalBenchmark.html
 
A

Andrew Thompson

S

Stefan Ram

Andrew Thompson said:
Wow! You must be running an old processor!

For privacy, the measured times all where scaled by the same
factor and, randomly, »1«, »0« or »-1« was added, in order not
to make public information about the hardware I use.

All that matters here is the /relative/ speed of the C++ and
the Java implementation.
 
T

Tom Hawtin

Stefan said:
So why is the Java program in the following benchmark still
slower than the C++ program?

Someone blogged about this the other day (but didn't have comments
turned on for non-blogspot users).

A problem with the original code is that it included I/O which added a
little to the time.

Also it used an unspecified implementation of ye olde 1.4. Using the
Server HotSpot on an AMD64 with Sun 1.6.0_01, I found performance over
twice that of Sun 1.4.2_14 with default options. I note you don't
specify versions or options for your tests.

Once you use modern implementations with reasonable options, the
differences mostly disappear. IIRC, the Java version can come out ahead.

There are reasons why Java should be slower. It defines reasonably well
how floating point should work, so it can be difficult to compile for
hardware that is less accurate. Also as the compilation is done at
runtime, some compromises are made to reduce the compile time.

Tom Hawtin
 
M

Mark Space

Stefan said:
For privacy, the measured times all where scaled by the same
factor and, randomly, »1«, »0« or »-1« was added, in order not
to make public information about the hardware I use.

All that matters here is the /relative/ speed of the C++ and
the Java implementation.
init:
deps-jar:
compile:
run:
24 ms
24 ms
23 ms
23 ms
22 ms
23 ms
23 ms
23 ms
22 ms
22 ms
22 ms
22 ms
22 ms
22 ms
23 ms
22 ms
22 ms
22 ms
22 ms
22 ms
BUILD SUCCESSFUL (total time: 0 seconds)
 
K

Kai Schwebke

Stefan said:
So why is the Java program in the following benchmark still
slower than the C++ program?

I got different results (using MAX_ITERATIONS 10000,
only latest stable timing listed)

java version "1.6.0_01" (-client)
200 ms

java version "1.6.0_01" (-server)
147 ms

g++ (GCC 3.4.6, no optimizations)
260 ms

g++ (GCC 3.4.6, -O3 -mpentiumpro)
160 ms


So on my system there is no difference between
optimized Java (server vm) and optimized C++ code
in this bench.


Kai
 
P

Paul Tomblin

In a previous article, (e-mail address removed)-berlin.de (Stefan Ram) said:
For privacy, the measured times all where scaled by the same
factor and, randomly, »1«, »0« or »-1« was added, in order not
to make public information about the hardware I use.

Either you are testing some weird hardware under an NDA, or you're an
idiot.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Paul said:
In a previous article, (e-mail address removed)-berlin.de (Stefan Ram) said:

Either you are testing some weird hardware under an NDA, or you're an
idiot.

Or he has sense of humor !

Arne
 
T

Tom Hawtin

Daniel said:

That's the monkey.

That points to the original article which has a JavaScript version
(comment out the first line). Even *without a warm up*, using the JDK
1.6 JavaScript implementation does give some interesting timings.

$ time ~/sun/jdk1.6.0_01-amd/bin/jrunscript -J-server -J-d64 -f
mandel.js >/dev/null

real 0m11.878s
user 0m11.737s
sys 0m0.116s
$ time ~/sun/jdk1.6.0_01-amd/bin/jrunscript -J-server -J-d64 -f
mandel.js >/dev/null

real 0m11.801s
user 0m11.621s
sys 0m0.116s
$ time ~/sun/jdk1.6.0_01-amd/bin/java -server -d64 Mandelbrot >/dev/null

real 0m0.470s
user 0m0.404s
sys 0m0.016s
$ time ~/sun/jdk1.6.0_01-amd/bin/java -server -d64 Mandelbrot >/dev/null

real 0m0.259s
user 0m0.192s
sys 0m0.032s

(Timings on an Ultra 20 with Opteron 148 running Ubuntu 7.04.)

Tom Hawtin
 
L

Lew

Kai said:
I got different results (using MAX_ITERATIONS 10000,
only latest stable timing listed)

java version "1.6.0_01" (-client)
200 ms

java version "1.6.0_01" (-server)
147 ms

g++ (GCC 3.4.6, no optimizations)
260 ms

g++ (GCC 3.4.6, -O3 -mpentiumpro)
160 ms


So on my system there is no difference between
optimized Java (server vm) and optimized C++ code
in this bench.

Given the breathlessly flame-baiting nature of the headline and original post,
I am unsurprised to find the truth to be more complex or even to contradict
the OP.

Also, OP, please consider a more standard indentation style.
 
L

Lew

I rewrote the loop to time 100 iterations and give the total and average
elapsed time, on a 2 GHz AMD-64 running Linux Fedora 6, Java version 1.6.0_01
and g++ 4.1.1:

g++ -O3:
$ ./mandelbrot
Elapsed: 4550 ms
iteration: 45.50 ms

g++ -O:
$ ./mandelbrot
Elapsed: 5140 ms
iteration: 51.40 ms

g++ unoptimized:
$ ./mandelbrot
Elapsed: 8320 ms
iteration: 83.20 ms

javac -g:none:
$ java -cp build/classes testit.Mandelbrot
Elapsed: 8133 ms
Iteration: 81.33 ms

FWIW, here are my timings with the original algorithm, modified for UNIX -
this measures each test cycle separately:

$ java -cp build/classes testit.Mandelbrot
57 ms
122 ms
52 ms
47 ms
171 ms
45 ms
160 ms
45 ms
43 ms
151 ms
43 ms
154 ms
45 ms
43 ms
145 ms
46 ms
150 ms
45 ms
43 ms
157 ms

$ ./mandelbrot (optimized -O3)
40 ms
50 ms
40 ms
50 ms
40 ms
50 ms
40 ms
50 ms
50 ms
50 ms
40 ms
40 ms
50 ms
40 ms
50 ms
50 ms
40 ms
50 ms
40 ms
50 ms
 
D

Daniel Dyer

I rewrote the loop to time 100 iterations and give the total and average
elapsed time, on a 2 GHz AMD-64 running Linux Fedora 6, Java version
1.6.0_01 and g++ 4.1.1: ....
javac -g:none:
$ java -cp build/classes testit.Mandelbrot
Elapsed: 8133 ms
Iteration: 81.33 ms

How about with the "-server" switch? As I understand it, there isn't such
a big difference between the client and server VMs in Java 6 as there was
in 5, but I'd guess it is still likley to be faster on the server VM.

Dan.
 
L

Lew

Daniel said:
How about with the "-server" switch? As I understand it, there isn't
such a big difference between the client and server VMs in Java 6 as
there was in 5, but I'd guess it is still likley to be faster on the
server VM.

$ java -server -cp build/classes testit.Mandelbrot
Elapsed: 8073 ms
Iteration: 80.73

I had run it before but didn't feel the need to cite the results. For one
thing, isn't "-server" better suited to long running processes?

Maybe if I up the loops to a few thousand cycles . . .
 
S

Steve Wampler

Daniel said:
How about with the "-server" switch? As I understand it, there isn't
such a big difference between the client and server VMs in Java 6 as
there was in 5, but I'd guess it is still likley to be faster on the
server VM.

In one of my worlds, with 1.6.0-b105 (Linux, CentOS4, dual-cpu Athlon), the server VM is slower at this
than the client VM:

->java -client Main
47 ms
50 ms
48 ms
48 ms
49 ms
48 ms
48 ms
49 ms
48 ms
48 ms
49 ms
48 ms
48 ms
49 ms
48 ms
48 ms
48 ms
49 ms
48 ms
48 ms
->java -server Main
72 ms
64 ms
64 ms
62 ms
58 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms
56 ms

Both are slower than g++4.1.1 (-O3):

->a.out
20 ms
20 ms
20 ms
20 ms
20 ms
20 ms
20 ms
30 ms
20 ms
20 ms
20 ms
20 ms
20 ms
20 ms
20 ms
30 ms
20 ms
20 ms
20 ms
20 ms

*However*, running the same code/options/OS/compilers/VMs on a dual Opteron yields
much better results for Java (the C++ times are indistinguishable from above [~same
clock speed on both systems]) and the server VM seems to win (over both client and
C++):

->java -client Main
93 ms
26 ms
24 ms
23 ms
23 ms
24 ms
23 ms
23 ms
24 ms
23 ms
23 ms
24 ms
26 ms
24 ms
23 ms
23 ms
23 ms
23 ms
23 ms
24 ms
->java -server Main
88 ms
20 ms
31 ms
18 ms
18 ms
21 ms
18 ms
19 ms
18 ms
18 ms
18 ms
18 ms
18 ms
18 ms
19 ms
18 ms
18 ms
18 ms
18 ms
19 ms
 
T

Twisted

I discovered the Jet optimiser produces better code that hand tuned
assembler. Seehttp://mindprod.com/jgloss/jet.html

Yup. Computers can now routinely beat the best humans at chess and
code-optimization, and they're even getting somewhere with Go now.
 
L

Luc The Perverse

Twisted said:
Yup. Computers can now routinely beat the best humans at chess and
code-optimization, and they're even getting somewhere with Go now.

I'm pretty sure the last part was a joke - but I don't get it. (And somehow
I don't think searching google for "go" is going to help)
 
L

Lars Enderin

Luc The Perverse skrev:
I'm pretty sure the last part was a joke - but I don't get it. (And somehow
I don't think searching google for "go" is going to help)

Somebody in another newsgroup made the same mistake about another common
word used as a program name, and refused to search for it. Actually, you
find the relevant links very early among the Google search results:
http://en.wikipedia.org/wiki/Go_(board_game)

And I don't think there was a joke in the reference.
 
P

Patricia Shanahan

Luc said:
I'm pretty sure the last part was a joke - but I don't get it. (And somehow
I don't think searching google for "go" is going to help)

Go, in this context, is a board game. See
http://en.wikipedia.org/wiki/Go_(board_game).

Incidentally, you underestimate Google. That Wikipedia page is the
second hit in a search for "go".

I read "getting somewhere with Go now" as meaning "Making progress on a
notoriously difficult EXPTIME-complete optimization problem compared to
humans who have studied that one problem for their whole lives, starting
in childhood."

Patricia
 

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,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top