9

Give me some of your thoughts on which is a better coding practice/makes more efficient code/looks prettier/whatever: Increasing and improving your ability to use if statements to anticipate and catch potential problems? Or simply making good use of try/catch in general?

Let's say this is for Java (if it matters).

Edit: I'm presently transitioning myself away from some admittedly out-dated and constrained current coding practices, but I'm a little torn on the necessity of doing so on a few points (such as this). I'm simply asking for some perspectives on this. Not a debate.

Daddy Warbox
  • 4,360
  • 8
  • 39
  • 56

9 Answers9

5

if blocks are slightly faster; if you aren't going to need a dozen of them, they're a better idea than try/catches. Exceptions should be exceptional, not every time the code runs. I use Exceptions for rare events like server disconnections (even though they happen a few times every day), and if blocks for any of my controllable variables.

mjk
  • 2,345
  • 4
  • 31
  • 31
Karl
  • 8,158
  • 5
  • 27
  • 29
  • 1
    If/else is generally faster than try/catch, but it's slower than no code at all. If you have several levels of call depth, an if/else at each call site to propagate errors by return value is liable to be slower than a single try/catch at the top in the case where no error actually occurs. – Steve Jessop Nov 30 '08 at 17:45
3

Regardless of what code you're writing, you'll end up using both. I can't speak for the Java runtime, but on the .NET runtime there's a performance hit associated with the use of try-catch blocks. As a result, I try to use them only in areas where I've got a clear way to handle the exception once caught (even if it's just logging the existence of a problem).

If you find yourself using a lot of either try-catch blocks or if-else blocks in your code, or your methods tend to be rather long, consider refactoring the code into a larger number of smaller methods. The intent of your logic will be easier to follow--as well as easier to unit test.

Scott Lawrence
  • 6,315
  • 12
  • 43
  • 61
2

I think if statements are better. You can't surround every line of code with a try..catch (well you can but you should not do it). You can surround a block of code with try catch but not every line.

And exceptions slow things down.

  • 2
    Exceptions only slow things down when they're actually thrown. So as long as you ensure they're only thrown in exceptional circumstances (where performance usually no longer matters because you're going to fail), it's not a concern. – Steve Jessop Nov 30 '08 at 17:46
  • @Steve Jessop If a try/catch is slower than an if statement, exceptions do slow things down even when not thrown(compared to if statements, that is). After all, a try/catch block, in the least, has to check if the exception was thrown at this portion of the code. – ThunderGr Oct 07 '13 at 06:32
  • 1
    @ThunderGr: this depends on programming language and implementation (of course), but for compiled languages it is *not* necessary for a try/catch block to check whether an exception was thrown at that point of the code. Rather, all catch blocks can be pulled out of line (say, collect them at the end of the function or even at the end of the executable), along with some meta-data about the code regions covered by their corresponding tries. This code/data need only be accessed when an exception is thrown and the runtime walks up the stack. – Steve Jessop Oct 07 '13 at 07:33
  • @Steve Jessop So, basically, you say that the compiler places the information for all try and catch blocks at a specific place and, when an exception occurs, the runtime checks this place to see if that block of code has a handler. It does make sense to me and sounds like the optimal implementation(it does take a hell lot of time when the exception is thrown, just like it is observed). Can we safely assume that the C#(.Net) implementation is like that? – ThunderGr Oct 07 '13 at 08:02
  • @ThunderGr: I don't know, but since the important question is whether try/catch blocks slow your code down when no exception is thrown, the real test is to time some non-failing code with and without them. – Steve Jessop Oct 07 '13 at 08:22
1

From what I've been told by more experienced developers and analysts, try/catch is more object oriented and if is more procedural.

I personally don't care.

I'm aware of the fact that a try/catch is slower and causes a performance hit, but if I'm going to use a dozen ifs to validate before I can do what I want to do, I will always use a try/catch to save on the number of lines of code.

It makes my life so much easier to not have to validate anything and if the statement fails, just do what I would have done in my 'else' block...in my 'catch' block.

Sometimes, I obviously enclose some if statements in a try/catch, but anyways.

I use an if when there's only a small number of things to validate (1 or 2) before doing what I need to do.

  • Finally an answer on here that talks about effectively communicating ideas and making things easier to understand and code. I feel many of the answers on this site forget that important fact about coding and talk about code in a perfect world. These answers typically give best practice advice on either run speed or safety but don't take into account the question and whether that solution even makes sense to implement. Best practices are usually fast and easy, but in real software corner cases arise where these practices can become long and complicated; and simplification to the code are needed – Zachary Kraus Mar 24 '15 at 02:54
1

My 2p: Using try/catch is best:

  • it makes it absolutely clear to other coders that you are doing exception handling
  • the compiler understands what you are doing and can perform more appropriate compile-time checks for you

In my experience, using if-conditional-logic makes it more difficult to distinguish error handling from business logic.

brabster
  • 39,706
  • 25
  • 137
  • 182
0

There's one thing that hasn't been mentioned here.

With an if-else statement, every time the code runs, at least 1 of the condition is guaranteed to be evaluated executed. I'm sure we all know how an if-else-elseif works, but to be clear... the if portion of the statement will always be evaluated, if it's false then the following else-if is evaluated, and so forth until only the else is left to evaluate.

So using an if-else statement will impact your performance. Not significantly (in most cases), but it does take CPU time to perform the evaluations.

try-catch statements, and correct me if I'm wrong, don't get considered at runtime until they're required (i.e. an exception is thrown). So simply wrapping your code in a try-catch will not affect performance until an exception is actually caught by it.

Also, it is not the catch that causes the performance hit, but the throw.

And one major point to make is, try-catch statements should NEVER be used for conditional logic. They should only be used for what they're designed for: exception handling!

Catching exceptions is essential, if you know what to do with them. If you have no way of properly handling the exception then you should let it go, for some code further up the chain may have a better way to handle it.

Its usually a good idea to have an exception hander at the absolute top level of your application to catch exceptions before they are seen by the user. In ASP.NET you can do this in the Application_Error event of the global.asax. In other languages/environments you would do so in your main loop, whatever that may be.

But note, there are some exceptions that are always best left uncaught. Sometimes when an exception happens it is an indicator that the state of your application has been severely compromised and cannot be trusted. The only safe thing to do is to kill and restart.

mikesigs
  • 7,762
  • 3
  • 30
  • 37
  • How can you say that a try/catch *is not considered at runtime until they are required*? This sounds like some kind of programming magic. There is no such thing as code that *is not considered until needed*. You need to have *at least* a check whether it is needed or not. – ThunderGr Oct 07 '13 at 06:38
  • The answer of Steve above, to my comment, provides a reasonable explanation why a try/catch block would not be considered at all until an exception occurs. It does require a virtual machine to run on, though and it looks like the *runtimes* of the languages provide this virtual machine. I doubt the CPU architecture has any support for exceptions. Does it? – ThunderGr Oct 07 '13 at 08:08
  • @ThunderGr I cant speak for all languages but mikesigs is correct at least for how C++ handles exceptions. In C++ the catch part of the block is ignored until an exception is thrown and the stack begins to unwind. As the stack unwinds, the code looks for a catch block to stop the unwind process. If none are found that are capable of excepting the exception. the program exits. – Zachary Kraus Mar 24 '15 at 03:02
  • @ZacharyKraus Where does it look for a "catch block" then, if not where I stated on my last comment here? – ThunderGr May 27 '15 at 12:47
  • @ThunderGr if you compile your code into assembly you can see there are two major things that contribute to exception handling __Unwind_Resume under a label statements and an except_table. These two areas of the assembly code work using the mechanism described on www.airs.com/blog/archive/464. Based on my simplistic understanding of that article, the exception handling is actually built into the compiled machine code and is called by jumping to the label where __Unwind_Resume is which begins both the exception handling process and the unwinding of the stack frame. – Zachary Kraus Jun 09 '15 at 02:27
  • @ThunderGr I think I might have made a slight error in the statement above. I think the order is slightly incorrect . The exception handling starts with the exception table and than I believe ends with Unwind_Resume. But that might also be incorrect as well. – Zachary Kraus Jun 09 '15 at 02:47
0

@PersonalPerson - Sorry, but this is just lazy coding. Rather than using a try-catch because there's too many if statements, why not refactor your code (i.e. put your validation logic in its own method). This will keep your code cleaner and more readable and maintain best practices for performance.

Never try to write your code to achieve the least # of lines. This will always end up badly. Sure you can find a more elegant way to write something that your coder-buddies will ooh and aah at, but it just makes things less readable.

I swear, I've worked with your code before, and it made my head hurt.

mikesigs
  • 7,762
  • 3
  • 30
  • 37
  • Unfortunately this statement really depends on the language. In some languages having an if statement with many tests, like 6 or 10+ tests, where the if statement will be called 90+% of the time can take a lot of processor time depending on how the code is optimized. In this case using a try catch block will tell both the processor and other coders this is the code i want to run most of the time which can potentially increase run speed depending on the language. In any other case, I agree with you, unless your using a duck typed language such as python. – Zachary Kraus Mar 24 '15 at 03:22
0

Using exceptions is universal method to notify other part of code that something wrong happened in loosely coupled way. Let imagine that if you would like to handle some exceptional condition by using if.. nad else.. you need to insert into different part of your code some arbitrary variables and other stuff which probably would easily led to have spaghetti code soon after.

Let next imagine that you are using any external library/package and it's author decided to put in his/her code other arbitrary way to handle wrong states - it would force you to adjust to its way of dealing with it - for example you would need to check if particular methods returns true or false or whatever.

Using exceptions makes handling errors much more easy - you just assume that if something goes wrong - the other code will throw exception, so you just wrap the code in try block and handle possible exception on your own way.

Jacek Dziurdzikowski
  • 1,393
  • 11
  • 20