3

The question says it all. Although the hit is not highly significant (I measured it to be between 1.5x to 2x slower), there's no difference between the byte code with try-catch and the byte code without it. So what makes it generally slower?

Pl. note that the question is not about overhead of throwing an exception, but of entering/leaving a try block.

EDIT: here's the code (run on Hotspot 1.6.0_31 server)

static void tryCatch()
{
    int i = 0;
    long l1 = getTime();
    for(int j = 0; j < 100000; j++)
    {
        try
        {
            i++;                
        }
        catch(Exception e)
        {

        }
    }
    long l2 = getTime();
    System.out.println("with try-catch: " + (l2 - l1) + ": " + i);      
}

static void noTryCatch()
{
    int i = 0;
    long l1 = getTime();
    for(int j = 0; j < 100000; j++)
    {
        i++;
    }
    long l2 = getTime();
    System.out.println("w/o  try-catch: " + (l2 - l1) + ": " + i);
}

static long getTime()
{
    return System.nanoTime();       
}
8
  • 12
    Please show how you measured this. Benchmarking is notoriously difficult to get right. Commented Apr 16, 2012 at 6:39
  • 3
    Also: try-catch is not only represented in the bytecode, but in code attributes of the method. In other words: you only see part of the try-catch implementation in the byte code. Commented Apr 16, 2012 at 6:41
  • 1
    Here's the question that probably has the answer you seek. Not sure if this can be considered duplicate question: stackoverflow.com/questions/2633834/… Commented Apr 16, 2012 at 6:43
  • @Hassan, agreed; but if try-catch is used sparingly, it won't affect the overall performance significantly. The hit I showed is seen when you execute it in long loops. Commented Apr 16, 2012 at 6:48
  • @Joachim Sauer: thanks! Could you pl. elaborate on it? Commented Apr 16, 2012 at 6:57

2 Answers 2

9

Since you have a micro-benchmark its is more likely you are testing how confusing the try/catch block is to the JVM compiler. For example, the JVM can be smart enough to change

for(int j = 0; j < 100000; j++) {
    i++;
}

into

i += 100000 * 1;

using the try/catch block may prevent the more aggresive optimisations, but might not make any difference for a more realistic block of code.


In any case I would normally change something like

for(int j = 0; j < 100000; j++) {
    try {
        // do something
    } catch(Exception e) {
        // break or return
    }
}

.

try {
    for(int j = 0; j < 100000; j++) {
        // do something
    }
} catch(Exception e) {
    // continue or return
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thx (and +1) for a detailed answer. But I want to measure the cost of 'entering' a try block. In the approach you've suggested, I probably won't be able to measure it.
I believe the cost is only that it might prevent a micro-optimisation of the JVM by making the code more complex. e.g. methods are typically only inlined if they are 35 bytes or less. a try/catch block could add a few bytes which could prevent inlining.
2

My microbenchmark for another question showed there is no significant difference between using/not using a try-catch block, with or without throwing exception in a block or not.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.