Sreekanth Karumanaghat
Sreekanth Karumanaghat

Reputation: 3403

Does try catch decrease efficiency?

Is there an efficiency difference between:-

public boolean canDivisionBeDone(int iA, int iB){

  try{
      float a = iA/iB;
    }catch(Exception e){
    return false;
 }

return true;
}

and

public boolean canDivisionBeDone(int iA, int iB){

 if(iB == 0){
     return false;
 }else{
         float a = iA/iB;
 }

return true;
}

If yes, why?

Upvotes: 0

Views: 729

Answers (3)

rustyx
rustyx

Reputation: 85371

Exceptions are for exceptional situations that you want to propagate back to the caller. Don't rely on exceptions during normal operation.

I would just write your code as:

public boolean canDivisionBeDone(int iA, int iB) {
    return iB != 0;
}

But to answer your question: try-catch-finally is implemented in Java using off-line exception tables, and as such, when no exception is thrown, is zero-overhead.

Here's how the bytecode of your two functions looks like:

  public boolean canDivisionBeDoneTryCatch(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: idiv
       3: i2f
       4: fstore_3
       5: goto          11
       8: astore_3
       9: iconst_0
      10: ireturn
      11: iconst_1
      12: ireturn
    Exception table:
       from    to  target type
           0     5     8   Class java/lang/Exception

  public boolean canDivisionBeDoneIf(int, int);
    Code:
       0: iload_2
       1: ifne          6
       4: iconst_0
       5: ireturn
       6: iload_1
       7: iload_2
       8: idiv
       9: i2f
      10: fstore_3
      11: iconst_1
      12: ireturn

As you can see the happy path is almost identical.

However, throwing an exception is expensive.

So yes, I would expect the exception version to be slightly slower, depending on the ratio of iB == 0 situations.

When in doubt, benchmark it.

Upvotes: 0

lexicore
lexicore

Reputation: 43671

From the coding point of view I would definitely prefer a conditional (a == 0 ? 0 : (a/b)), not exception handling. This is actually not an exceptional situation so exception should not be used for control flow here.

Concerning the efficiency, I wrote a micro-benchmark to test this:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

    private int a = 10;
    private int b = (int) Math.floor(Math.random());

    @Benchmark
    public float conditional() {
        if (b == 0) {
            return 0;
        } else {
            return a / b;
        }
    }

    @Benchmark
    public float exceptional() {
        try {
            return a / b;
        } catch (ArithmeticException aex) {
            return 0;
        }
    }
}

Results:

Benchmark                Mode  Cnt  Score   Error  Units
MyBenchmark.conditional  avgt  200  7.346 ± 0.326  ns/op
MyBenchmark.exceptional  avgt  200  8.166 ± 0.448  ns/op

As I am quite new to JMH, I am not sure my benchmark is correct. But taking results at the face value, the "exceptional" approach is somewhat (~10%) slower. To be honest, I've expected much greater difference.

Upvotes: 1

Hamid Ghasemi
Hamid Ghasemi

Reputation: 892

using try has no expenses by itself, but if the using block creates too much exceptions, you should try to review your code.

Creating an exception in Java is a very slow operation. Expect that throwing an exception will cost you around 1-5 microseconds. Nearly all this time is spent on filling in the exception thread stack. The deeper the stack trace is, the more time it will take to populate it.

for more details read here

Upvotes: 1

Related Questions