This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Cost of having try-catch statements?
Andrew Haley wrote:
Martin Egholm Nielsen writes:
> > > I was wondering: Is there any significant cost in having "unused"
> > > try-catches in my code?
> > > That is, I have a method that 99.99% of the times invoked never throws a
> > > given exception. However, in case it does, I need to log it...
> > The only cost is the unwinder tables, (which are not read into memory
> > unless your exception is thrown) and the handler itself, which may
> > cause some instruction cache presure.
> So practically no overhead?
That's the idea. Really, if there is any significant overhead for an
unused handler that would be a bug.
Being curious, I tried a micro benchmark (Main.java, attached).
The code just calls a method on an instance of class Main that then
proceeds to call another method (that will never throw an exception, it
simply increments a member to be not completely empty). In the first
case there is nothing happening besides the second function being
called, in the second case I have wrapped a try/catch around the call.
The time given is how long it takes to execute 10,000,000 calls in a for
loop. Each test is repeated twice before any measurement takes place.
Here is the output (and what I did to compile the code):
----------------------------------------------------------------
C:\work\workspace-c++\MixAndMatch>gcj -o Main.exe -O2 Main.java --main=Main
C:\work\workspace-c++\MixAndMatch>Main.exe
without try/catch 250ms
with try/catch 1332ms
without try/catch 261ms
with try/catch 1322ms
C:\work\workspace-c++\MixAndMatch>javac Main.java
C:\work\workspace-c++\MixAndMatch>java -classpath . Main
without try/catch 80ms
with try/catch 321ms
without try/catch 70ms
with try/catch 320ms
C:\work\workspace-c++\MixAndMatch>gcj -o Main2.exe -O2 Main.class
--main=Main
C:\work\workspace-c++\MixAndMatch>Main2.exe
without try/catch 311ms
with try/catch 1352ms
without try/catch 310ms
with try/catch 1342ms
----------------------------------------------------------------
This seems to indicate that in both gcj and J2SDK1.4.2_04 on Windows
there is significant overhead. (And that the Sun JVM seems to be 4 times
faster at this contrived "benchmark").
Harald
PS: I ran this on a 1GHz Centrino Notebook with 512mb Ram, CPU speed
locked at 1GHz
public class Main {
int i = 0;
public void foo() {
++i;
}
public void foo1() {
foo();
}
public void foo2() {
try {
foo();
} catch (RuntimeException re) {
System.out.println("caught "+re);
}
}
private static int LOOP_COUNT = 10000000;
public static void main(String[] args) {
Main m = new Main();
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo1();
}
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo2();
}
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo1();
}
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo2();
}
long then;
long now;
then = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo1();
}
now = System.currentTimeMillis();
System.out.println("without try/catch "+(now-then)+"ms");
then = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo2();
}
now = System.currentTimeMillis();
System.out.println("with try/catch "+(now-then)+"ms");
then = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo1();
}
now = System.currentTimeMillis();
System.out.println("without try/catch "+(now-then)+"ms");
then = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
m.foo2();
}
now = System.currentTimeMillis();
System.out.println("with try/catch "+(now-then)+"ms");
}
}