When I execute the simple code sample below via Eclipse (version 3.5.2, on Ubuntu 10.04, java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2) OpenJDK Server VM (build 19.0-b09, mixed mode)), it takes about 10 seconds. When I execute it from my shell (using the same priority and java version), it takes about 40 seconds.
for (int i = 0; i<1000*1000; i++) {
System.out.println(Math.cos(i));
}
I also tried other programs, varying in runtime and amount of output: Each one was much slower in the shell. This was independent of the order of execution. The minimum percentage difference was 85 seconds in Eclipse vs. 145 seconds in shell for a program with very little output.
What's the reason?
-
4I presume Eclipse uses an already-running JVM, whereas when you run java manually, it has to start one up.Jeremy– Jeremy2011年08月26日 14:26:37 +00:00Commented Aug 26, 2011 at 14:26
-
Are you sure the JDK your console calls is OpenJDK Server VM (build 19.0-b09, mixed mode) ? Try running the shell version with Eclipse open and running some idle test to see if the fact there already is a JVM already launched impacts that behavior as @Jeremy Heiler suggests wisely.Kheldar– Kheldar2011年08月26日 14:27:14 +00:00Commented Aug 26, 2011 at 14:27
-
4Could it be that the slowness is in printing to the console, especially if you're using a compositing desktop like GNOME 3 or Unity? Try redirecting output to a file, and re-test both.michel-lind– michel-lind2011年08月26日 14:27:45 +00:00Commented Aug 26, 2011 at 14:27
-
Please see stackoverflow.com/questions/7124489/… for a very similar problem and possible answer.George Cummins– George Cummins2011年08月26日 14:29:34 +00:00Commented Aug 26, 2011 at 14:29
-
Hah @Hircus, one behavior, many possibilities ;)Kheldar– Kheldar2011年08月26日 14:30:20 +00:00Commented Aug 26, 2011 at 14:30
4 Answers 4
It's because you're timing your terminal. Some terminals are just bog-slow when displaying/scrolling text. And your terminal is line buffered, vs the eclipse console likely have more buffering - leading to your program having to wait for your terminal after every line it prints.
Try redirecting the output of your program to a file or /dev/null, and time it.
On my system this makes a bit difference with your little loop:
$ time java T --snip - 1M lines of output-- real 0m24.746s user 0m2.403s sys 0m1.597s $ time java T>output real 0m5.172s user 0m2.800s sys 0m2.707s
-
1Wow, my terminal IS bug-slow. I did suspect the output and hence reduced it in my experiments, but didn't completely avoid it (so that no dead code elimination would occur). I didn't believe that an output once in a while could have such a huge impact, so I didn't investigate more. After redirecting the output: no more time difference.DaveFar– DaveFar2011年08月26日 14:40:40 +00:00Commented Aug 26, 2011 at 14:40
Since by far the most time your program spends in doing output, the overall time of execution is very much depending on the time your system call takes for that. So putting it on the regular console seems to be much slower than the output window in eclipse, but that does not mean, your program itself is executed faster.
Just direct all output into a file and you won't see much difference any more.
Two possibilities come to mind. First, in Eclipse, the Java machinery is already fired up; perhaps running from the shell incurs significant start-up overhead. Try timing just the loop itself (using System.currentTimeMillis()
).
Second, perhaps your configuration is such that Java running from the shell has JIT disabled. That might significantly slow down a program. Check your environment variables for anything that might disable the JIT compiler.
-
I also did some samples with a micro-benchmark (Execution Time Measurement Library), and it showed about the same slowdown.DaveFar– DaveFar2011年08月26日 14:30:07 +00:00Commented Aug 26, 2011 at 14:30
-
I cannot find anything relevant in my shell environment. Could there be some configuration hidden elsewhere? Hm, I'll just check whether my java program runs even slower when I deactivate JIT via an option...DaveFar– DaveFar2011年08月26日 14:35:23 +00:00Commented Aug 26, 2011 at 14:35
-
JIT was active, Eclipse's console is just much faster than the shell's (+5 to nos and Geziefer).DaveFar– DaveFar2011年08月26日 15:08:21 +00:00Commented Aug 26, 2011 at 15:08
-
Yes, I see that nos and Geziefer figured it out. Well done to them!Ted Hopp– Ted Hopp2011年08月26日 15:15:37 +00:00Commented Aug 26, 2011 at 15:15
How are you measuring time? By using System.nanoTime()
? (If you are measuring time externally, keep in mind the time to bootstrap the VM).
Try to do the following:
- Modify your main method to do a warm up run first without recording times.
- Then measure the time for several others run using
System.nanoTime()
. - See if there's any significant difference of performance between the averaged time measured from console and Eclipse.
-
+5 for your last suggestion. Wouldn't have guessed that the shell can be so much slower than Eclipse's console :-0DaveFar– DaveFar2011年08月26日 15:09:42 +00:00Commented Aug 26, 2011 at 15:09