views:

226

answers:

4

Is there any performance benefit (particularly in C++ or Java) in keeping the size of try block small [aside from it being more informative to the reader as to which statement can throw].

Given the following method where i do not want to throw out of the method.

void function() throws Exception
{
    statement1
    statement2
    statement3 // can throw
    statement4
    statement5
}

Is it better to do this:

Option 1

void function()
{
    try {
        statement1
        statement2
        statement3 // can throw
        statement4
        statement5
    }
    catch (...) {
    }
}

or

Option 2

void function()
{
    statement1
    statement2

    boolean success = false;
    try {
        statement3 // can throw
        success = true;
    }
    catch (...) {
    }

    if (success)
    {
        statement4
        statement5
    }
}
+3  A: 

At least with the compilers and exception handling mechanisms I've seen, there should be no difference. The depth at which an exception throw is nested can make a difference, but only when the exception is thrown and the general agreement is that in this case performance is something you can generally ignore.

Jerry Coffin
I believe in some older versions of compilers there was a penalty to even opening up a try, but now-a-days they have moved that work now to the exception block to improve performance an encourage developers to use try blocks more
slf
@slf: is that the case in Java? In C++ at least, there's still quite a bit of overhead to it. (Although it still varies by platform)
jalf
@jalf: actually, I was speaking of Objective-C. I'm not sure of the specifics in each c++ compiler unfortunately. Is there a spreadsheet somewhere? I'd love to see the numbers
slf
I don't know if it can still be considered up-to-date, but there was a treatment of exception overhead in TR18015 5.4 - http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf - according to that, decent implementations using the "table" approach should incur no runtime overhead on entering try-blocks.
Georg Fritzsche
from Scott Meyers More Effective C++: "Different compilers implement try blocks indifferent ways, so the cost varies from compiler to compiler. As a roughestimate, expect your overall code size to increase by 5-10% and yourruntime to go up by a similar amount if you use try blocks. This assumes no exceptions are thrown; what we’re discussing here is just thecost of having try blocks in your programs. To minimize this cost, youshould avoid unnecessary try blocks."
slf
@gf: As far as I know, that's the approach taken by 64-bit Windows. 32-bit doesn't though, and so there you get the runtime overhead. Not sure on other platforms. The problem with the table approach is that it uses more memory
jalf
@jalf: Ah, interesting. I haven't yet stumbled upon good information about where what approach is used. I should probably have written "no runtime time overhead".
Georg Fritzsche
+2  A: 

I'm not addressing the performance issue, I think readability is more important unless you know you have a bottle-neck. That being said:

It really depends on how related statement1-5 are. If it is one logical operation that is performed in 5 steps I prefer option 1.

Setting a success flag at the end of the try block in Option 2 is very ugly and error-prone, I would not recommend this in any case.

Trent
+1 If 4 and 5 are never executed when 3 throws an exception, option 2 just makes it harder to understand what's happening
Geoff Reedy
As far as readability is concerned, isn't option 2 more readable in that it's clearer to the reader which line is throwing. I would think that's an important piece of information.
Integer
+1 Option 2 is ugly, harder to understand and harder to maintain.
Kevin Gale
@Integer, then why use exceptions at all? I personally find it easier to read the normal flow as one block and the exception handling as a separate section below. If you want you can check an error code returned from each function called (like in C, etc.) but I don't care for mixing logic and error handling like that.
Trent
A: 

option 1 is fine. THe fact that some of the lines don't throw is not relevant. For a start just look at the code, it looks crisper. There is no perf hit

you will however get lectures about indiscriminately eating all exceptions and ignoring them

This is the type of mismatch thing you get when transitioning from a layer of code that uses exceptions (or even embraces them) and a layer that does not. It seems that the layer above you doesnt like exceptions, and that the layer below does. Is there a reason that the layer above you doesn't like exceptions. What would happen if you needed to explain to the layer above why statement3 failed. THen you have to write horrible exception to return code conversion functions.

pm100
A: 

As others have said, there should be only minimal difference in the generated code between these cases. The "cost" of exception handling relates to how many temporary objects must be destroyed when the stack is unwound (and to a lesser degree, the number of places the code has to jump to do it). This scales with the depth of the stack -- how many function calls between where the exception is thrown and where it is caught -- not with the number of instructions executed between the beginning of the try block and the throw.

Andy Ross