4

Possible Duplicate:
Should java try blocks be scoped as tightly as possible?

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
    }
}
Community
  • 1
  • 1
Integer
  • 199
  • 9
  • On most implementations, try/catch blocks cost almost nothing until an exception is thrown. And of course once an exception is thrown you should no longer care about performance, but fixing the problem. – GManNickG Jan 22 '10 at 19:35
  • 1
    Also, why on Earth are you silencing an exception like this? That said, option 1 is cleaner. A comment like you have gives the same benefit of number 2 (knowing which function can throw) without the ugly. – GManNickG Jan 22 '10 at 19:37
  • 2
    @GMan Why am i silencing an exception? Because it was a simple example off the top of my head to illustrate my question on performance. I suppose you'll next say the code snippets don't compile. – Integer Jan 22 '10 at 19:41
  • Why so defensive? The problem comes from you saying "Which is better" without defining better. What's the real problem? You want to know the easiest way to run a sequence of statements, where one might possibly throw? The first one does just that. The second is the lame version of the first, with no advantage I can spot. – GManNickG Jan 22 '10 at 19:52
  • I thought I conveyed the context of "better" twice: The question reads "Is there any performance benefit (particularly in C++ or Java) in keeping the size of try block small" and the title reads "Limiting try block scope. Does it matter?". I thought it was pretty clear what i was asking. Considering the whole thing is essentially pseudocode, i found it silly that you question why i'm silencing an exception. To which i had to roll my eyes. But thanks anyway. – Integer Jan 22 '10 at 20:01
  • To be frank, because you even considered number two, it indicates you probably perform other bad code practices, like silencing exceptions. I simply wanted to curve you away from that route. If it was just a snippet, then feel no need to be defensive. – GManNickG Jan 22 '10 at 20:06
  • My consideration of #2 is purely tied to whether or not the scope size of the try block affects performance. The fact you bring up an irrelevant point of silencing an exception indicated to me you had missed that point entirely therefore i was trying to bring you back to center. To which you again misinterpreted that, to my being defensive. – Integer Jan 23 '10 at 05:07
  • This is a near duplicate of http://stackoverflow.com/questions/2633834/should-java-try-blocks-be-scoped-as-tightly-as-possible. There are better answers there. – Iain Samuel McLean Elder Aug 18 '11 at 13:35

4 Answers4

3

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
  • 476,176
  • 80
  • 629
  • 1,111
  • 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 Jan 22 '10 at 19:13
  • @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 Jan 22 '10 at 19:16
  • @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 Jan 22 '10 at 19:31
  • 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 Jan 22 '10 at 19:38
  • from Scott Meyers More Effective C++: "Different compilers implement try blocks in different ways, so the cost varies from compiler to compiler. As a rough estimate, expect your overall code size to increase by 5-10% and your runtime 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 the cost of having try blocks in your programs. To minimize this cost, you should avoid unnecessary try blocks." – slf Jan 22 '10 at 19:40
  • @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 Jan 22 '10 at 20:57
  • @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 Jan 22 '10 at 22:26
2

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
  • 13,249
  • 4
  • 39
  • 36
  • +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 Jan 22 '10 at 19:13
  • 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 Jan 22 '10 at 19:30
  • 2
    +1 Option 2 is ugly, harder to understand and harder to maintain. – Kevin Gale Jan 22 '10 at 19:34
  • 1
    @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 Jan 22 '10 at 20:46
1

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
  • 48,078
  • 23
  • 82
  • 145
1

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
  • 11,699
  • 1
  • 34
  • 31