Java vs C++ speed (IO & Sorting)

I

Ian Collins

Razii said:
Yeah, this was quicker BUT IT FAILED THE QUALITY TEST..
Do you have to shout at everyone?
The "a" in your string is always more than "z"
Yes, that was a consequence of the randomness of the bits in the numbers
returned form rand(). A quick check shows a standard deviation of about
0.4% for the number returned and about 4% for the bit groups.

Using a better random number function (lrand48()) gives much better
results with bit shifting (deviation of about 0.4%).
 
R

Razii

Using a better random number function (lrand48()) gives much better
results with bit shifting (deviation of about 0.4%).

If the test showed you that, cut and paste the function exactly so we
can test it. Why didn't you?
 
Z

zionz

If the test showed you that, cut and paste the function exactly so we
can test it. Why didn't you?

I tried with that, the results were pretty good, i obtained very
similar results to yours (+/-10%)

void getRandomString(std::string &s)
{
int n,i;
srand48(time(0));
s.reserve(len);

for(i = 0 ; i < len; i+=4){
n = lrand48();
s+= (char) (n % 26 + 97);
s+= (char) ( (n>>8) % 26 + 97);
s+= (char) ( (n>>16) % 26 + 97);
s+= (char) ( (n>>24) % 26 + 97);
}
}

The speed was similar to the java version:

Java 1662 ms
C++ 1716 ms
 
I

Ian Collins

Razii said:
If the test showed you that, cut and paste the function exactly so we
can test it. Why didn't you?

Because I didn't feel like it.

What are your requirements for randomness you never did post them.

Try this:

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

std::string cr( len, '\0' );

const size_t byN = (len/8)*8;

size_t i(0);

while( i < byN )
{
const int iNumber( lrand48() );

cr[i++] = iNumber % 26 + 97;

cr[i++] = (iNumber>>1) % 26 + 97;
cr[i++] = (iNumber>>2) % 26 + 97;
cr[i++] = (iNumber>>3) % 26 + 97;
cr[i++] = (iNumber>>4) % 26 + 97;
cr[i++] = (iNumber>>5) % 26 + 97;

cr[i++] = (iNumber>>6) % 26 + 97;
cr[i++] = (iNumber>>7) % 26 + 97;
}
while( i < len )
{
const int iNumber( rand() );

cr[i++] = iNumber % 26 + 97;
}

s.swap( cr );
}

You can add more shifts until your conditions for randomness are broken.
 
R

Razii

void getRandomString(std::string &s)
{
int n,i;
srand48(time(0));
s.reserve(len);

for(i = 0 ; i < len; i+=4){
n = lrand48();
s+= (char) (n % 26 + 97);
s+= (char) ( (n>>8) % 26 + 97);
s+= (char) ( (n>>16) % 26 + 97);
s+= (char) ( (n>>24) % 26 + 97);
}
}

Find.cpp(61) : error C3861: 'srand48': identifier not found
Find.cpp(65) : error C3861: 'lrand48': identifier not found

even after I added?

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <stdlib.h>
 
R

Razii

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

std::string cr( len, '\0' );

const size_t byN = (len/8)*8;

size_t i(0);

while( i < byN )
{
const int iNumber( lrand48() );

cr[i++] = iNumber % 26 + 97;

cr[i++] = (iNumber>>1) % 26 + 97;
cr[i++] = (iNumber>>2) % 26 + 97;
cr[i++] = (iNumber>>3) % 26 + 97;
cr[i++] = (iNumber>>4) % 26 + 97;
cr[i++] = (iNumber>>5) % 26 + 97;

cr[i++] = (iNumber>>6) % 26 + 97;
cr[i++] = (iNumber>>7) % 26 + 97;
}
while( i < len )
{
const int iNumber( rand() );

cr[i++] = iNumber % 26 + 97;
}

s.swap( cr );
}


error C3861: 'srand48': identifier not found
 
Z

zionz

Find.cpp(61) : error C3861: 'srand48': identifier not found
Find.cpp(65) : error C3861: 'lrand48': identifier not found

even after I added?

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <stdlib.h>

True, i thought that those functions were standard but they are not,
sorry about that.
But even using the standard rand(), and this code:

void getRandomString(std::string &s)
{
int n,i;
srand(time(0));
s.reserve(len);

for(i = 0 ; i < len; i+=4){
n = rand();
s+= (char) (n % 26 + 97);
s+= (char) ( (n>>8) % 26 + 97);
s+= (char) ( (n>>16) % 26 + 97);
s+= (char) ( (n>>24) % 26 + 97);
}
}

int main()
{
int i,ac,zc,a,b;
ac=zc=a=b=0;

clock_t start=clock();
string s;
getRandomString(s);
clock_t endt=clock();
cout << "Time: " << (double)(endt-start) / (double)CLOCKS_PER_SEC <<
endl;

for(i=0; i<s.size(); i++){
if(s == 'a'){ a++;}
if(s == 'z'){ b++;}
if(s.substr(i,4) == "adam"){zc++;}
if(s.substr(i,4) == "zion"){ac++;}
}

cout << "Results: " << endl << ac << endl << zc << endl;
cout << a << endl << b << endl;
}

I get the following output:
Time: 1.7
Results:
112
105
1929679
1831740

Don't you think this is random enough?
 
R

Razii

I get the following output:
Time: 1.7
Results:
112
105
1929679
1831740

There is something wrong with your testing (I will check your main
later).

I am getting this with your function...

C:\>Find a
Number of a: 2596757
Time: 1734 ms

C:\>Find z
Number of z: 870938
Time: 1421 ms

C:\>Find zion
Number of zion: 0
Time: 1484 ms

C:\>Find adam
Number of adam: 0
Time: 1531 ms

The reason why I think something is wrong with your testing is that
when I use my old c++ random function and use the same test, I get

C:\>Find a
Number of a: 1924474
Time: 2578 ms

C:\>Find z
Number of z: 1922329
Time: 2718 ms

C:\>Find zion
Number of zion: 112
Time: 2656 ms

C:\>Find adam
Number of adam: 99
Time: 2515 ms

So obviously my test is correct...
 
R

Razii

There is something wrong with your testing (I will check your main
later).

Yuor testing was right but the result you posted above was wrong. I
ran your version and got

C:\>Find2
Time: 1.453
Results:
0
0
25971040
870186
 
Z

zionz

There is something wrong with your testing (I will check your main
later).

I am getting this with your function...

C:\>Find a
Number of a: 2596757
Time: 1734 ms

C:\>Find z
Number of z: 870938
Time: 1421 ms

C:\>Find zion
Number of zion: 0
Time: 1484 ms

C:\>Find adam
Number of adam: 0
Time: 1531 ms

The reason why I think something is wrong with your testing is that
when I use my old c++ random function and use the same test, I get

C:\>Find a
Number of a: 1924474
Time: 2578 ms

C:\>Find z
Number of z: 1922329
Time: 2718 ms

C:\>Find zion
Number of zion: 112
Time: 2656 ms

C:\>Find adam
Number of adam: 99
Time: 2515 ms

So obviously my test is correct...

I guess the code is not good :(, thats why depending on the compiler
it may not work as intended.
Btw i think its important to mention that here the java version is
taking ~100mb ram while the C++ version uses only 50 mb.
 
M

Michael DOUBEZ

Razii a écrit :
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


Using the program at the en of this mail compiled with (g++ -DNDEBUG
-O3), I get the following results:

D:\gnuwin32>java -Xmx256m Find2 && Find2.exe
Time: 3445 ms
Time: 3070 ms

D:\gnuwin32>java -Xmx256m Find2 && Find2.exe
Time: 3444 ms
Time: 3070 ms

D:\gnuwin32>java -Xmx256m Find2 && Find2.exe
Time: 3444 ms
Time: 3101 ms

I could not start the -sever flavour of java, perhaps it makes a difference.

Michael

-------------

#include <string>
#include <cstdlib>
#include <ctime>
#include <sys/time.h>
#include<iostream>

using namespace ::std;

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

s.clear();
s.reserve(len);

for( int i = 0 ; i < len ; ++i )
{
s.push_back(rand() % 26 + 97);
}
}

int main()
{
string str;

timeval tstart,tstop;

//begin measure
gettimeofday(&tstart,NULL);

getRandomString(str,50000000);

//end measure
gettimeofday(&tstop,NULL);

//compute diffrence time
long long start, stop;
start=tstart.tv_sec*1000000+tstart.tv_usec;
stop=tstop.tv_sec*1000000+tstop.tv_usec;
cout <<"Time : "<<((stop-start)/1000)<<" ms"<<endl;

return 0;
}
 
M

Martin York

Just to chime in and write the C++ in a more C++ style.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

const int len = 50000000;

struct myRandom
{
char operator()() const { return std::rand() % 26 + 'a';}
};

int main( int argc, char *argv[])
{
std::vector<char> data(len);

clock_t start = clock();
std::generate_n(&data[0],len,myRandom());
std::string str(data.begin(),data.end());
clock_t end = clock();

std::cout <<"Time: " <<
double(end-start)/CLOCKS_PER_SEC * 1000 << " ms" << std::endl;
}
cat Find.java
import java.util.*;

public class Find{

public static void main(String[] arg)
{
final int len = 50000000;

long start = System.currentTimeMillis();
String s = randomString(len);
long end = System.currentTimeMillis();

System.out.println("Time: " + (end - start) + " ms");
}

//returns a String of length l 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);

}
java -Xmx256m Find && ./Find
Time: 3654 ms
Time: 873.487 ms
 
R

Razii

I could not start the -sever flavour of java, perhaps it makes a difference.

The -server version is in JDK bin directory....If your path is set to
check the JDK bin directory first, -server sould work.
 
R

Razii

I could not start the -sever flavour of java, perhaps it makes a difference.

Yes -server makes a difference (go to JDK bin directory to find it)

C:\>java -Xmx256m Find razi
Number of razi: 108
Time: 3509 ms

C:\>java -Xmx256m -server Find razi
Number of razi: 106
Time: 1879 ms
 
L

Lew

Michael said:
I could not start the -sever [sic] flavour of java, perhaps it makes a
difference.

In my own experience the '-server' option roughly doubles a Java program's
performance, for most.

How are you trying to use it, and what happens that prevents you from starting
it? What messages do you get? (That's two related questions for which I am
requesting answers.)
 
L

Lew

Razii said:
The -server version is in JDK bin directory....If your path is set to
check the JDK bin directory first, -server sould work.

That doesn't make sense. Options to the 'java' command aren't in any
directory. It's the 'java' executable itself that resides in the file system.
Options are provided upon its invocation. There is no separate "version" of
the executable.

The JDK bin directory need not be first in the PATH, it only needs to be in
the PATH. This allows one to invoke the 'java' command without specifying an
absolute path to it, but doesn't affect what options one provides to that command.
 

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

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top