Reputation: 3403
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
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
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
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