views:

145

answers:

5

Hi.

I've read pretty often, that using try-catch is quite slow compared to normal code. Now I wonder if the number of caught exceptions affects the performance of the code or not.

So is

try{
  ...
}
catch(StrangeException e){
  ...
}

slower than

try{
  ...
}
catch(StrangeException e){
  ...
}
catch(MysteriousException e){
  ...
}
catch(FrighteningException e){
  ...
}

?

Of course I'm only referring to the code in the try-clause and if no exception is caught.

A: 

The only way to know for sure with questions of performance is to carefully test it yourself.

But if you asked me to bet, I would bet that it doesn't make a measurable difference at all, and that even using try/catch versus not using it doesn't make much of a difference, as long as no exceptions are actually thrown (which they shouldn't be, in the normal case).

Avi
+6  A: 

What you've read is wrong. A significant overhead is incurred when an exception is genuinely thrown - normally the overhead is minimal when there are no exceptions. One exception to this is that it may well affect inlining - so if you have a method which is being called in a tight loop, you may find it doesn't get inlined if it has try/catch blocks. Likewise just the presence of code may affect cache coherency and other subtleties... but in most situations this won't be a bottleneck.

I don't think I've ever seen a real-life situation where exceptions aren't getting thrown, but having try/catch blocks has been a performance problem. As ever, you should write the cleanest code you can, and test how it performs. Only consider bending the ideal design out of shape for performance reasons when you've got clear evidence that the changes are both necessary and useful.

Jon Skeet
As a corollary, if you have code where the volume of exceptions is a performance issue, you're most likely not using exceptions properly.
John
@John: Agreed - although in this case the OP explicitly stated that he's interested in the performance where exceptions *aren't* being thrown.
Jon Skeet
+3  A: 

The cost of a try / catch block is essentially zero if no exceptions are actually thrown. The number of catch clauses makes no difference.

The cost of exceptions occurs only when they actually get thrown:

  • Constructing the exception object is very expensive, because of the cost of the fillInStackTrace() step. This has to create and initialize a data structure containing key details of all frames on the current thread stack. In the worst case, there could be thousands of them.

  • Throwing and catching exceptions is a bit expensive. In the worst case, the JVM needs to do the equivalent of an instanceof for each catch clause of each try / catch block. This is where having lots of catch clauses could make a difference to performance.

Stephen C
A: 

As far as I can remember from my old days of reading bytecode, the number of catch clauses has no significant effect on performance.

When an exception occurs, the JVM knows to jump to the bytecode sequence which implements the catch clause by looking up the exception in a table that is part of the class' bytecode. In general, each method that catches an exception is associated with an exception table that is part of the class file, along with the method's bytecode. The exception table has an entry for each exception that's caught, by each try-block. Each entry contains: the start and end points, the program counter (PC) offset within the bytecode sequence to jump to, and a constant pool index of the exception type (i.e. class) that is being caught.

If an exception is thrown during the execution of a method, the JVM searches through the exception table for a match. A matches occurs if the current PC is within the range specified by the entry, and if the exception class thrown is the one specified by the entry (or is a subclass of it).

So the answer to your question depends on how this search is implemented. As far as I know, the JVM searches through the table in the same order in which the entries appear in the table and when the first match is found, the JVM sets the PC to the new location and continues execution from there.

I think that unless you have A LOT of exceptions you wouldn't notice a significant impact, but if I were you and if this issue was critical to me, I would benchmark this on the particular JVM that you're using.

Ori

Ori
A: 

I do remember reading that someone tested this and found that performance actually was affected in this case, even though you probably wouldn't expect it to be. (A quick Google search doesn't show it up though, so I don't remember how many catch blocks there were, or which Java version it was found on.)

Matthew Wilson