public inbox for java@gcc.gnu.org
 help / color / mirror / Atom feed
* Performances with gcj
@ 2008-08-10 18:17 Benjamin de Dardel
  2008-08-11  4:10 ` David Daney
  0 siblings, 1 reply; 4+ messages in thread
From: Benjamin de Dardel @ 2008-08-10 18:17 UTC (permalink / raw)
  To: java

[-- Attachment #1: Type: text/plain, Size: 1189 bytes --]

Hi all,

I had to release a program that executes an external process and gets 
its standard output.
I implemented a solution with threads and pipes to redirect inputs and 
outputs (cf PipeTest.java).

I choose the 'find /' command to test it.
I'm very surprised about gcj performances which are 5x slowly than sun jvm.
In fact, I expected that my compiled program would be faster than all jvm.

Do you have an idea about these differences ?
Is that the gnu classpath implementation which is quiet slow ?

Regards,
Benjamin

# test1 : bash
$ time find /
real    2m6.054s
user    0m5.260s
sys     0m6.990s

# test2 : compilation with gcj
$ gcj --main=PipeTest -o test.bin PipeTest.java
$ time test.bin
real    18m50.632s
user    4m56.380s
sys     8m31.940s

real    19m38.148s
user    5m9.660s
sys     9m44.710s

# test3: interpretation with gij
$ gcj -C PipeTest.java
$ time gij PipeTest

real    22m39.882s
user    6m7.580s
sys     10m26.350s

# test4 : interpretation with java
$ javac PipeTest.java
$ time java PipeTest
real    3m35.035s
user    1m18.710s
sys     0m11.730s

##### compilers #####
$ gcj --version
gcj (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu6)

$ javac -version
javac 1.6.0_03

[-- Attachment #2: PipeTest.java --]
[-- Type: text/x-java, Size: 2658 bytes --]


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeTest {
	public static void main(String args[]) {
		System.out.println("START");
		try { /* set up pipes */
			PipedOutputStream pout1 = new PipedOutputStream();
			PipedInputStream pin1 = new PipedInputStream(pout1);

			PipedOutputStream pout2 = new PipedOutputStream();
			PipedInputStream pin2 = new PipedInputStream(pout2);

			/* construct threads */

			Producer prod = new Producer(pout1);
			Filter filt = new Filter(pin1, pout2);
			Consumer cons = new Consumer(pin2);

			/* start threads */

			prod.start();
			filt.start();
			cons.start();

			prod.join();
			filt.join();
			cons.join();
		} catch (IOException e) {
			System.out.println("Error1 : " + e.getMessage());
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("STOP");
	}
}

class Producer extends Thread {

	private DataOutputStream out;

	public Producer(OutputStream os) {
		out = new DataOutputStream(os);
	}

	public void run() {
		try {
			Process p1 = Runtime.getRuntime().exec("find /");
			try {
				InputStreamReader isr = new InputStreamReader(p1
						.getInputStream());
				BufferedReader br = new BufferedReader(isr);
				String line = null;
				while ((line = br.readLine()) != null) {
					out.writeBytes(line + "\n");
					out.flush();
				}
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
			out.close();
		} catch (Exception e) {
			System.out.println("Error: " + e);
		}
	}

}

class Filter extends Thread {

	private BufferedReader in;
	private DataOutputStream out;

	public Filter(InputStream is, OutputStream os) {
		in = new BufferedReader(new InputStreamReader(is));
		out = new DataOutputStream(os);
	}

	public void run() {
		String s = "";
		while (s != null) {
			try {
				s = in.readLine();
				// TODO apply filters
				out.writeBytes(s + "\n");

			} catch (IOException e) {
				System.out.println("Error: " + e);
			}
		}
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class Consumer extends Thread {

	private BufferedReader in;

	public Consumer(InputStream is) {
		in = new BufferedReader(new InputStreamReader(is));
	}

	public void run() {
		String s = "";
		while (s != null) {
			try {
				s = in.readLine();
				if (s != null) {
					System.out.println("LINE = " + s);
				}
			} catch (IOException e) {
				System.out.println("Error: " + e);
			}
		}
	}
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Performances with gcj
  2008-08-10 18:17 Performances with gcj Benjamin de Dardel
@ 2008-08-11  4:10 ` David Daney
  2008-08-12 19:10   ` Benjamin de Dardel
  0 siblings, 1 reply; 4+ messages in thread
From: David Daney @ 2008-08-11  4:10 UTC (permalink / raw)
  To: benjamin.de-dardel; +Cc: java

Benjamin de Dardel wrote:
> Hi all,
>
> I had to release a program that executes an external process and gets 
> its standard output.
> I implemented a solution with threads and pipes to redirect inputs and 
> outputs (cf PipeTest.java).
>
> I choose the 'find /' command to test it.
> I'm very surprised about gcj performances which are 5x slowly than sun 
> jvm.
> In fact, I expected that my compiled program would be faster than all 
> jvm.
>
> Do you have an idea about these differences ?
> Is that the gnu classpath implementation which is quiet slow ?
>
I have not profiled it, but it is not too surprising.

You could try buffering the process' input stream before sending it 
through the InputStreamReader.

I suspect that the slowdown is in the character set conversion.  You are 
using the default converter.  You could also try something like US-ASCII 
and see if that speeds things up.

David Daney

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Performances with gcj
  2008-08-11  4:10 ` David Daney
@ 2008-08-12 19:10   ` Benjamin de Dardel
  0 siblings, 0 replies; 4+ messages in thread
From: Benjamin de Dardel @ 2008-08-12 19:10 UTC (permalink / raw)
  To: David Daney; +Cc: java

[-- Attachment #1: Type: text/plain, Size: 2263 bytes --]

David Daney a écrit :
> Benjamin de Dardel wrote:
>   
>> Hi all,
>>
>> I had to release a program that executes an external process and gets 
>> its standard output.
>> I implemented a solution with threads and pipes to redirect inputs and 
>> outputs (cf PipeTest.java).
>>
>> I choose the 'find /' command to test it.
>> I'm very surprised about gcj performances which are 5x slowly than sun 
>> jvm.
>> In fact, I expected that my compiled program would be faster than all 
>> jvm.
>>
>> Do you have an idea about these differences ?
>> Is that the gnu classpath implementation which is quiet slow ?
>>
>>     
> I have not profiled it, but it is not too surprising.
>
> You could try buffering the process' input stream before sending it 
> through the InputStreamReader.
>
> I suspect that the slowdown is in the character set conversion.  You are 
> using the default converter.  You could also try something like US-ASCII 
> and see if that speeds things up.
>
> David Daney
>
>
>
>   
Hi David,

I rewrite the tests, using class BufferedInputStream.
Result seems to be more exact now :
- compilation is faster than interpretation,
- optimization increase performances.

Thanks for you help,
Benjamin

##### find / #####
# test1 : bash
$ time find /
real    2m6.541s
user    0m5.510s
sys     0m5.740s

# test2 : compilation with gcj
$ gcj --main=PipeTest -o test.bin PipeTest.java
$ time test.bin
real    8m3.392s
user    1m56.100s
sys     1m49.100s

# test3 : optimized compilation with gcj (level 2)
$ gcj -C PipeTest.java
$ gcj -O2 --main=PipeTest -o test.bin PipeTest.class Consumer.class 
Producer.class
real    7m18.718s
user    1m40.960s
sys     1m47.970s

# test4 : optimized compilation with gcj (level 3)
$ gcj -C PipeTest.java
$ gcj -O2 --main=PipeTest -o test.bin PipeTest.class Consumer.class 
Producer.class
real    6m55.568s
user    1m40.500s
sys     1m36.700s

# test5 : interpretation with gcj
$ gcj -C PipeTest.java
$ time gij PipeTest
real    9m59.789s
user    2m53.010s
sys     1m54.280s

# test6 : interpretation with java
$ javac PipeTest.java
$ time java PipeTest
real    11m45.988s
user    3m25.510s
sys     2m5.290s

##### compilers #####
$ gcj --version
gcj (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu6)

$ javac -version
javac 1.6.0_03


[-- Attachment #2: PipeTest.java --]
[-- Type: text/x-java, Size: 2635 bytes --]


/**
 * http://www.java2s.com/Code/Java/File-Input-Output/PipeTest.htm
 * @version 1.20 1999-04-23
 * @author Cay Horstmann
 */

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeTest {

	public static void main(String args[]) {
		System.out.println("START");
		try { /* set up pipes */
			PipedOutputStream pout1 = new PipedOutputStream();
			PipedInputStream pin1 = new PipedInputStream(pout1);

			/* construct threads */

			Producer prod = new Producer(pout1);
			Consumer cons = new Consumer(pin1);

			/* start threads */

			prod.start();
			cons.start();

			prod.join();
			cons.join();
		} catch (IOException e) {
			System.out.println("Error1 : " + e.getMessage());
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("STOP");
	}
}

class Producer extends Thread {

	// TODO BufferedWriter
	private DataOutputStream out;

	public Producer(OutputStream os) {
		out = new DataOutputStream(os);
	}

	public void run() {
		try {
			Process p1 = Runtime.getRuntime().exec("find /");
			try {
				
//				InputStreamReader isr = new InputStreamReader(p1.getInputStream());
//				BufferedReader br = new BufferedReader(isr);
//				String line = null;
//				while ((line = br.readLine()) != null) {
//					out.writeBytes(line + "\n");
//					out.flush();
//				}
				
				BufferedInputStream bis = new BufferedInputStream((p1.getInputStream()));
				int c;				
				while ((c = bis.read()) != -1) {
					out.write(c);
					out.flush();
				} 
				
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
			out.close();
		} catch (Exception e) {
			System.out.println("Error: " + e);
		}
	}

}

class Consumer extends Thread {

	//private BufferedReader in;
	private BufferedInputStream in;

	public Consumer(InputStream is) {
		//in = new BufferedReader(new InputStreamReader(is));
		in = new BufferedInputStream(is);
	}

	public void run() {
		int c;				
		try {
			while ((c = in.read()) != -1) {
				System.out.print((char)c);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
//		String s = "";
//		while (s != null) {
//			try {
//				s = in.readLine();
//				if (s != null) {
//					System.out.println("LINE = " + s);
//				}
//			} catch (IOException e) {
//				System.out.println("Error: " + e);
//			}
//		}
	}
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Performances with gcj
  2008-08-10 18:30 ffileppo
@ 2008-08-10 21:34 ` Benjamin de Dardel
  0 siblings, 0 replies; 4+ messages in thread
From: Benjamin de Dardel @ 2008-08-10 21:34 UTC (permalink / raw)
  To: ffileppo; +Cc: java

Hi Francesco,

Thanks for your response. I had already tryed to optimize the code with 
the java file, but it didn't work :
$ gcj -0 --main=PipeTest -o test.bin PipeTest.java
gcj: unrecognized option '-0'

With class files, compilation works... but performances decrease !
May be it's beacause of the threads. I don't know. I'll do some other 
tests in the next days.

# test5
$ gcj -C PipeTest.java
$ gcj -O2 --main=PipeTest -o test.bin PipeTest.class Consumer.class 
Producer.class Filter.class

real    21m59.844s
user    5m26.070s
sys     9m52.130s

# test6
$ gcj -C PipeTest.java
$ gcj -O3 --main=PipeTest -o test.bin PipeTest.class Consumer.class 
Producer.class Filter.class

real    25m34.394s
user    6m12.250s
sys     11m4.440s

ffileppo a écrit :
>> Hi all,
>>
>> I had to release a program that executes an external process and gets 
>> its standard output.
>> I implemented a solution with threads and pipes to redirect inputs and 
>> outputs (cf PipeTest.java).
>>
>> I choose the 'find /' command to test it.
>> I'm very surprised about gcj performances which are 5x slowly than sun jvm.
>> In fact, I expected that my compiled program would be faster than all jvm.
>>
>> Do you have an idea about these differences ?
>> Is that the gnu classpath implementation which is quiet slow ?
>>
>> Regards,
>> Benjamin
>>
>> # test1 : bash
>> $ time find /
>> real    2m6.054s
>> user    0m5.260s
>> sys     0m6.990s
>>
>> # test2 : compilation with gcj
>> $ gcj --main=PipeTest -o test.bin PipeTest.java
>> $ time test.bin
>> real    18m50.632s
>> user    4m56.380s
>> sys     8m31.940s
>>
>> real    19m38.148s
>> user    5m9.660s
>> sys     9m44.710s
>>
>> # test3: interpretation with gij
>> $ gcj -C PipeTest.java
>> $ time gij PipeTest
>>
>> real    22m39.882s
>> user    6m7.580s
>> sys     10m26.350s
>>
>> # test4 : interpretation with java
>> $ javac PipeTest.java
>> $ time java PipeTest
>> real    3m35.035s
>> user    1m18.710s
>> sys     0m11.730s
>>
>> ##### compilers #####
>> $ gcj --version
>> gcj (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu6)
>>
>> $ javac -version
>> javac 1.6.0_03
>>
>>     
>
> You need to pass -O2 or -O3 option to gcj compiler (no optimization is enabled by default).
> Please take a look at other posts about gcj performance (http://gcc.gnu.org/ml/java/2008-05/msg00017.html).
>
> Francesco
>
>
>
>
>   

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-08-12 19:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-10 18:17 Performances with gcj Benjamin de Dardel
2008-08-11  4:10 ` David Daney
2008-08-12 19:10   ` Benjamin de Dardel
2008-08-10 18:30 ffileppo
2008-08-10 21:34 ` Performances " Benjamin de Dardel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).