Java try/catch performance, is it recommended to keep what is inside the try clause to a minimum?
Considering you have code like this:
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
Now I know, there is in fact a performance hit when constructing the exception, specifically unwinding the stack. And I have also read several articles pointing to a slight performance hit when entering try/catch blocks, but none of the articles seem to conclude anything.
My question is, is it recommended to keep the lines inside the try catch to bare minimum?, i.e. ONLY have inside the try clause the lines that can actually throw the exception you are catching. Does the code inside the try clause run slower or cause any performance hit?.
But more important what it is the best practice/more readable solution considering doing this:
try {
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
}
catch (MyCheckedException e) {
//handle it
}
or :
try {
doSomething() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn't complete and why)
continue;
}
//do some assignements calculations
try {
doAnotherThing() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn't complete and why)
continue;
}
This is considering that you will handle ALL this checked exceptions exactly the same way of course.
Is it recommended to keep the lines inside the try catch to bare minimum?
No. Can't imagine how you could think that the length of a try
block or indeed of any block can have any impact on performance.
Does the code inside the try clause run slower or cause any performance hit?.
No.
As you observed, exceptions only incur performance costs when thrown.
If you're concerned about 'try' performance, surely the thing to do is keep the code inside to a maximum?
In your example here, the real performance hit is if both doSomething() and doAnotherThing() both throw exceptions. Entering a try-block is fast, until it throws an exception.
It really comes down to what your situation is. If you need to do the same thing when MyCheckedException is thrown either way, I'd consider it both more readable and more performant to have them both in the same try block, but if you need to handle the two different situations differently then of course it makes more sense to separate them.
Edit: I read the end of your comment, you're assuming handling both the same way, in which case I'd put them both in the same try-block.
I'm not sure which one is slower, but don't forget that a try
block is control flow. You should make the control flow match what you're trying to accomplish. For me, the choice between
try {
// op 1.
// op 2.
/ ...
// op n.
}
catch ( MyCheckedException error )
{
// handle any `MyException` in op 1, 2 ... n.
}
and sepearate catch
blocks for each is mainly a decision of whether I want to do different handling for each op, keep executing until op n
regardless of errors or try to execute all of them and fail at the first error.
Write clean, readable code, and then search for bottlenecks. If existing experiments can't conclude to basic guidelines, then I suspect that's not where you'll find your bottlenecks anyways.
Having try-blocks should have basically zero performance effect in any decent JVM. The real hit comes when an exception is actually thrown.
You can read this article to get an idea of how the JVM implements exception handling in bytecode: it creates "exception tables" that map regions of code to catch/finally blocks, so:
- Bytecode for a try-block is the same as for a standard { } block
- The only extra cost in the non-throwing case is that of having the "exception table" loaded in memory.
Of course, when an exception is thrown there is a lot of stack work going on, so it is going to have a cost. Anyway, it is not nearly as bad as with SEH (.NET exceptions).
Your code should only handle the exceptions it can do something about, the others should be re-thrown.
The amount of code in the try block does not cause slowdowns, hitting the catch block does. But unless you are trying to write real high performance code, I would not worry about it.