Java vs C++ speed (IO & Sorting)

D

dave_mikesell

No, silly. You inform the user of the minimum system requirements for your
product, just like everyone else does.

What if they run other Java applications that require an older JVM?
Seems bundling it would be the safest option.
 
R

Razii

What if they run other Java applications that require an older JVM?
Seems bundling it would be the safest option.

Why won't the newer VM run the old applications? If there are such
cases, they are rare.
 
R

Razii

I wanted to create a string with 50 million chars (small letters from
a to z), but the program crashed...

//the function returns a string of length len
// with chars from a to z (small letters).
const len = 50000000;
void randomString(string &s)
{
srand((unsigned)std::time(0));
char cr [len+1];
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = iNumber;
}

cr [len] ='\0';
s.assign(cr);
}

The above crashed when the length, len = 50000000 (50 million). How
come? Since I was trying to test something (something else this time,
as I have nothing else to do:)), an hour earlier I was doing the same
thing in java without any problem.

//returns a String of length len with lowercase letters from a to z
static String randomString(int len)
{
char[] cr = new char[len];
Random rd = new Random();
for (int i = 0; i < len; i++){
int num = rd.nextInt(26) + 97;
cr = (char) num;
}

return new String(cr);

}

They both look the same ... why the c++ version crashes?
 
J

James Kanze

I am not sure what you say when "without complete
implementation". A java library file (jar file), is sufficient
to use it (no need to have the full source code) The javadoc
is usually provided also separately from the code.

How do you create a java library file without the
implementation?
It is sure one can not compile a java program using a library
without the jar file but I don't think this happens often. But
in C++ you need the libraries files - at linking time ok but
you need them - so what is the difference ? (well except if
you want to test compilation, you can do it in java too, just
more work making a dummy jar file)

In large applications, it is usual for client teams to begin
coding (and compiling, but not linking, of course) before the
teams providing the library have finished coding. More
importantly, in large applications, it is usual that the normal
coder cannot check out an exported header file without
authorization; the "interface" (the parts on which client code
depends) is not to be modified lightly.

C++ is far from perfect in this regard, but it still seems to
work better than Java in practice.
As a user you only need to know the interface and what a class
does: this is described in javadoc. A .java file is the
implementation of a class. If you want the definition (as a
user of the class), you use javadoc (no need for a header
file)

I can't compile against Javadoc. And I can't really get the
Java doc until the class implementation is complete, which is
completely backwards. Normally, what's generated by Java doc
should be reviewed before a single line of code is written.
Javadoc is for user of your class. It does not prevent you
from making specification and design documentation before
writing your code. And yes when it comes to detailled design i
write javadoc before code in method.

Yes, but there is still the problem that all of this is in a
single file: the java doc, the class definition, and function
implementations. Ideally, all three would be separate, with the
class definition automatically generated from the doc. Failing
that, putting the doc and the class definition in the same file
is a good compromize. (For the low level documentation, of
course---you still need class diagrams, etc. But there's no
difference between Java and C++ in that regard.) But in a large
project, it is very important to keep the parts on which client
code depends (i.e. the class definition) separate from the
implementation details (the function internals). The
responsibility for each lies in different hands.
That is wrong. I suppose you are thinking in the CLASSPATH
environment variable which may be set in a user enviroment.
When you provide a java program, you also provide the way to
launch it (for exemple a batch file) in which you specify the
classpath *you* want. Put the classpath to libraries bundled
with your binaries, and you be sure your program will work.

In other words, you need an external tool. In some cases, this
is true for C++ as well, but in simple cases, you just
distribute a single executable file, and that's it. It makes
deployment a lot simpler. Of course, in many cases, you can
also just distribute a single jar file. But you run
significantly more risks than with a statically linked
executable.

Obviously, you pay for this with a lack of flexibility: my
statically linked executable (generated on a Sun Sparc, under
Solaris) may not run on your machine (if your machine is a PC
under Windows, for example). Your JAR file will. Provided the
user is careful with the versions of the JVM he uses, and what
he does with CLASSPATH. For some applications, the added
flexibility is worth the risks, for others, the risks aren't
acceptable, and the flexibility isn't needed.

Note that formally, this really doesn't depend on the language.
The C++ standard certainly allows implementations along the
lines of what Java does, and I think you could also create a
Java implementation which partially linked statically (and would
not link in anything which wasn't "pre-linked" statically). In
practice, however, I've never heard of either.
Classpath had been a problem for a lot of people in the early
years of java because it was new (when you think of it now, it
ist obvious)

In other words: it's a problem, but time has provided the
work-arounds, and made them common practice. (We've got a lot
of those in C++ as well.)
Static linking is not perfect otherwise there would not have
been dynamic libraries; dynamic libraries is not perfect:
often you have to provide your own copy to be sure to be
compatible. This is not a java problem.

Not per se, but the Java language definition does encourage
implementations to dynamically load each class. (The runtime
has to behave "as if" the class wasn't loaded until the specific
runtime event that would have triggered the load.) And the
usual implementations do. Where as the usual C++
implementations (at least on the platforms I work on: Solaris
and Linux) generate static libraries by default. (FWIW: even in
C++, I think dynamic loading is used much more than it should
be.)

[...]
Well i guess the documentation was not accurate enough if it
did not mention that if overrided the method should not return
null.

I don't think it mentionned it, but I think the specified
semantics of the program made it more or less implicitly clear.
The problem is that we didn't return null intentionally. We
returned a variable which had been initialized by the
constructor. The constructor which hadn't been called.
Bad use or design of classes is not a java specific problem.

Allowing the call of a virtual function to go through to a class
whose constructor has yet to be called is bad design in the
language itself. Calling a virtual function in the constructor
of a base class is probably bad design as well---in this case,
in the Java standard library. (But to be fair, Swing is,
globally, a lot better than any of the C++ GUI libraries I've
seen.)

The real point, of course, is that Java and C++ are distinctly
different languages, designed with different goals in mind.
Most of my work in on large scale, more or less critical
servers, and the design criteria of Java make it inappropriate
here. For the server itself---it's the language of choice for
GUI based administrator clients, for example.
 
J

James Kanze

James Kanze said:

[...]
No, silly. You inform the user of the minimum system
requirements for your product, just like everyone else does.
You don't buy them a computer, either.

Just a nit, but... Most of the work I've done has been on turn
key systems. We don't provide a "program", but a solution.
Hardware and software, fully integrated.

So yes, we do buy them a computer. We also install the OS on
it, and test our program with the exact configuration (including
patches) under which it will run.

We also have conventional penalties for downtime (typically
something like 5000 Euro per minute) in the contract. So we do
sort of want to be sure that it works.

But of course, that's only one development situation. (One in
which the arguments relative to class path are pretty
irrelevant, since if the application were in Java, we'd supply
the JVM, and set up the rc files to start it correctly.) In
other cases, we provide a simple executable---and deployment is
a lot easier if you can provide just a single executable, and
require nothing else on the machine but the OS.
 
J

James Kanze

Why won't the newer VM run the old applications?

Why does any software not work the way it should? When I worked
in Java, we definitly had a problem once with this: the user had
unknowingly upgraded when visiting some site in the browser, and
our software suddenly stopped working. I think the error was in
our code (this was some time ago), but the code did work with
the version we'd used to test it.
 
H

hurcan solter

I wanted to create a string with 50 million chars (small letters from
a to z), but the program crashed...

//the function returns a string of length len
// with chars from a to z (small letters).
const len = 50000000;
void randomString(string &s)
{
srand((unsigned)std::time(0));
char cr [len+1];
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = iNumber;
}

cr [len] ='\0';
s.assign(cr);

}

The above crashed when the length, len = 50000000 (50 million). How
come? Since I was trying to test something (something else this time,
as I have nothing else to do:)), an hour earlier I was doing the same
thing in java without any problem.

//returns a String of length len with lowercase letters from a to z
static String randomString(int len)
{
char[] cr = new char[len];
Random rd = new Random();
for (int i = 0; i < len; i++){
int num = rd.nextInt(26) + 97;
cr = (char) num;
}

return new String(cr);

}

They both look the same ... why the c++ version crashes?


They look same,but they are not. You are trying to create and array of
5000000 chars on the stack,create it on the freestore as you did with
java then it wont ( Although i feel like I am goaded to say this :Z
 
D

dave_mikesell

Why won't the newer VM run the old applications? If there are such
cases, they are rare.

My client is running into problems now going from 1.4.2 to 1.5.0,
where a library function now throws an exception that it didn't
before, breaking existing code that is shared among applications.
Some of these have the requirement to upgrade, others don't, so it
creates a problem.

Doesn't seem like a huge problem, but this is a relatively small jump
in VM versions on the same base operating system, with an application
that is not overly complex, and it broke.
 
D

dave_mikesell

My client is running into problems now going from 1.4.2 to 1.5.0,
where a library function now throws an exception that it didn't
before, breaking existing code that is shared among applications.
Some of these have the requirement to upgrade, others don't, so it
creates a problem.


By the way, here is the bug report. By "fixing" this in 1.5, they
broke my client's shared library that is used by multiple apps, some
requiring 1.4, others 1.5.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4749727
 
A

Alf P. Steinbach

* Razii:
I wanted to create a string with 50 million chars (small letters from
a to z), but the program crashed...

//the function returns a string of length len
// with chars from a to z (small letters).
const len = 50000000;
void randomString(string &s)
{
srand((unsigned)std::time(0));
char cr [len+1];
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = iNumber;
}

cr [len] ='\0';
s.assign(cr);
}

The above crashed when the length, len = 50000000 (50 million). How
come?


You have allocated about 50 MB locally, in practice on the stack.

Try using std::string.

Since I was trying to test something (something else this time,
as I have nothing else to do:)), an hour earlier I was doing the same
thing in java without any problem.

//returns a String of length len with lowercase letters from a to z
static String randomString(int len)
{
char[] cr = new char[len];
Random rd = new Random();
for (int i = 0; i < len; i++){
int num = rd.nextInt(26) + 97;
cr = (char) num;
}

return new String(cr);


void getRandomString( std::string& s, size_t len )
{
std::string cr( len );
...

s.swap( cr );
}

Cheers, & hth.,

- Alf
 
L

Lew

James said:
So yes, we do buy them a computer. We also install the OS on
it, and test our program with the exact configuration (including
patches) under which it will run.

What, your customer doesn't pay for it? It's still the customer buying it,
after disclosure that your equipment is part of the minimum required system.
It just happens that the minimum system is the one you sell.
 
R

red floyd

Razii said:
I wanted to create a string with 50 million chars (small letters from
a to z), but the program crashed...

//the function returns a string of length len
// with chars from a to z (small letters).
const len = 50000000;
This won't compile, as far as I know... Implicit int is illegal.
void randomString(string &s)
{
srand((unsigned)std::time(0));
char cr [len+1];
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = iNumber;
}

cr [len] ='\0';
s.assign(cr);
}

The above crashed when the length, len = 50000000 (50 million). How
come? Since I was trying to test something (something else this time,
as I have nothing else to do:)), an hour earlier I was doing the same
thing in java without any problem.

//returns a String of length len with lowercase letters from a to z
static String randomString(int len)
{
char[] cr = new char[len];
Random rd = new Random();
for (int i = 0; i < len; i++){
int num = rd.nextInt(26) + 97;
cr = (char) num;
}

return new String(cr);

}

They both look the same ... why the c++ version crashes?
 
R

Razii

What you gave me was much slower for 50 milion char string..

C:\>cl /O2 /GL Find.cpp /link /ltcg

Time: 3281 ms

For the java version I posted....
C:\>java -Xmx256m -server Find

Time: 1719 ms

so now you have proven without a doubt that c++ is 2 times slower :)


//this is what you suggested
void getRandomString( std::string& s, size_t len )
{
srand((unsigned)std::time(0));

std::string cr( len, '\0' );
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr += (char) iNumber;
}

s.swap( cr );
}
 
A

Alf P. Steinbach

* Razii:
What you gave me was much slower for 50 milion char string..

C:\>cl /O2 /GL Find.cpp /link /ltcg

Time: 3281 ms

For the java version I posted....
C:\>java -Xmx256m -server Find

Time: 1719 ms

so now you have proven without a doubt that c++ is 2 times slower :)


//this is what you suggested
void getRandomString( std::string& s, size_t len )
{
srand((unsigned)std::time(0));

std::string cr( len, '\0' );
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr += (char) iNumber;

No, when I wrote "..." I meant "insert your old code, exactly as it was, here".

The statement above ends up adding 50 million chars to a string that's already
50 million chars.

Not that it's necessarily a bad way to do it (it has a little overhead but is
generally less brittle, i.e. more safe, than indexing code), but then the
declaration of cr should leave cr as initially empty: either originally empty
string and append, or originally 50 million char string and indexing.
}

s.swap( cr );
}


Cheers, & hth.,

- Alf
 
M

Mark Thornton

How do you control which JRE your user uses? Do you bundle that as
well?

Actually quite a few do exactly that. In my own case the data supplied
with application can run to several GB, so a few extra MB for a JRE is
of no consequence. However there is now a -version:release option which
allows specification of the required version on the command line. The
version specification need not be an exact match but can be something
like this: -version:"1.5.0_04 1.5*&1.5.1_02+" (example stolen from the
JDK documentation). WebStart has long had this capability.

Mark Thornton
 
R

Razii

No, when I wrote "..." I meant "insert your old code, exactly as it was, here".

Ok, so I have this now...

void getRandomString( std::string& s, size_t len )
{
srand((unsigned)std::time(0));

std::string cr( len, '\0' );
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = (char) iNumber;
}

s.swap( cr );
}

Time: 2531 ms

that's still slower than java version..

Time: 1719 ms
 
Z

zionztp

No, when I wrote "..." I meant "insert your old code, exactly as it was, here".

Ok, so I have this now...

void getRandomString( std::string& s, size_t len )
{
srand((unsigned)std::time(0));

std::string cr( len, '\0' );
for( int i = 0 ; i < len ; ++i )
{
int iNumber;
iNumber = rand() % 26 + 97;
cr = (char) iNumber;
}

s.swap( cr );
}

Time: 2531 ms

that's still slower than java version..

Time: 1719 ms


In my system the rand() function is taking most of the time in this
test, and since it generates a 4 bytes random number i tried the
following:

n = rand();
memcpy(&n, nt, 4);
b[i+0] = nt[0] % 26 + 97;
b[i+1] = nt[1] % 26 + 97;
b[i+2] = nt[2] % 26 + 97;
b[i+3] = nt[3] % 26 + 97;

This resulted into 6x faster execution.
 

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
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top