3

My knowledge with try catch is limited. But i wonder if it can be used to gain performance.

Example, i am creating this voxel engine where a function is like this:

Block GetBlockInChunk(Vector Position){
    if(InBound(Position)){
        return Database.GetBlock();
    }
    return null;
}

Here it has to check bounds of the given position, with using try catch, then you can remove them?

Block GetBlockInChunk(Vector Position){
    try{
        return Database.GetBlock();
    }
    catch{
        return null;
    }
}

I feel like this is probably terrible practice, but i am curious.

filipot
  • 176
  • 2
  • 10
  • `try..catch` introduces overhead and doesn't boost performance AFAIK. – Zein Makki Oct 02 '16 at 18:41
  • 1
    It is also for *exceptional* situations, not to be used in default situations. Here checking for bounds would seem a better way to go than letting it throw exceptions. – Sami Kuhmonen Oct 02 '16 at 18:44
  • See http://stackoverflow.com/questions/8687113/if-condition-vs-exception-handler – Abion47 Oct 02 '16 at 18:44
  • Ah alright, makes sense. :) – filipot Oct 02 '16 at 18:45
  • 2
    You should avoid exceptions. Only use an exception where you didn't expect something. `try` isn't slow, `catch` is. – Jeroen van Langen Oct 02 '16 at 18:45
  • We shouldn't overgeneralize, but yes, in this case it seems a bad idea. Unqualified `catch` is *definitely a very bad idea* as well. But if you are wondering about performance, why don't you run some quick tests? In this instance the results will be glaring. – Jon Oct 02 '16 at 18:45
  • @JeroenvanLangen What if exceptions are rare to none, and it is mostly caused by human error, and the InBound check is more just for safety. Would it be a good idea then? – filipot Oct 02 '16 at 18:47
  • Possible duplicate of [try catch performance](http://stackoverflow.com/questions/1350264/try-catch-performance) – Filip Cordas Oct 02 '16 at 18:49
  • @Vermacian55, You'd probably check the user input ones and solve it there. For example, It's better to use `int.TryParse()` then using exceptions. This looks like a method that is called many times. So you should avoid exceptions. – Jeroen van Langen Oct 02 '16 at 18:49
  • Thanks for the link! @Abion47 – filipot Oct 02 '16 at 18:49

2 Answers2

8

The link I provided in the above comment shows a description of why you shouldn't ever use a try-catch when an if-statement would prevent the exception from being thrown, but in the interest of showing performance in terms of actual numbers, I wrote this quick little test program.

Stopwatch watch = new Stopwatch();

int[] testArray = new int[] { 1, 2, 3, 4, 5 };
int? test = null;

watch.Start();
for (int i = 0; i < 10000; i++)
{
    try
    {
        testArray[(int)test] = 0;
    }
    catch { }
}
watch.Stop();

Console.WriteLine("try-catch result:");
Console.WriteLine(watch.Elapsed);
Console.WriteLine();

watch.Restart();
for (int i = 0; i < 10000; i++)
{
    if (test != null)
        testArray[(int)test] = 0;
}
watch.Stop();

Console.WriteLine("if-statement result:");
Console.WriteLine(watch.Elapsed);

The result of the program is this:

try-catch result:
00:00:32.6764911

if-statement result:
00:00:00.0001047

As you can see, the try-catch approach introduces significant overhead when an exception gets caught, taking over 30 seconds to complete 10,000 cycles on my machine. The if-statement, on the other hand, runs so fast that it is basically instantaneous. Compared to the try-catch, this is a performance improvement in the neighborhood of 3,000,000%.

(This isn't a rigorous benchmark, and there are ways to write it and run it differently to get more precise numbers, but this should give you a good idea of just how much more efficient it is to use an if-statement over a try-catch whenever possible.)

Abion47
  • 22,211
  • 4
  • 65
  • 88
0

It is about 2 years later, but it is still relevant...

I respect the other replies but I believe there is a basic misunderstanding here for the purpose of try-catch. Try Catch is a very effective way within the C# and dotnet, to identify errors over the development and the life of the code. It is never intended to be a tool to use different, and if it is been fire, it means that you have a bug that needs to be fixed.

The problem it comes to solve is the standard error message that stops the code and then you need to dig in. With try and catch you can know in which method the problem occurs and narrow down the search.

As standard, I wrap ALL my methods with try-catch and added an additional functionality that writes the error message with the name of the method and additional essential information like time, and some helpful anchors of data to a debug file, which I can access even when the code is in production. This is priceless!

As far as performance, if the try-catch doesn't fire (which should be normal), there is no performance reduction, as it is merely a simple warper. If someone is really into a high level of performance and every fraction matter, it is possible to eliminate it using precompiler conditions (#if...).

Hope this is helpful.

Shai
  • 9
  • 1
  • 2
    I'm sorry, it does not necessarily mean there is a "bug". Exceptions can occur, for example, when writing a file and the disk space is exhausted. It is "exceptional", and needs to be handled, but it is not a bug in the code. – KevinO Oct 31 '18 at 23:42
  • This answer reminds me of something I did as a junior developer in my first job twenty years ago. I also wrapped every single method in the (VB6 at the time) equivalent of a try-catch for exactly the same reason - wanting to debug errors. I can't find anything in this answer that is either true or helpful or good practise, hence the downvote. – bboyle1234 Apr 11 '20 at 13:50
  • 1
    @bboyle1234 to be fair there is some helpful information which is: `As far as performance, if the try-catch doesn't fire (which should be normal), there is no performance reduction`, which is something that took me a while to understand. The loss of performance only happens if the stack trace is generated. @Shai `Try ... Catch`ing every method is not necessary because the stack trace already includes the information your are looking for. – Ama Aug 17 '20 at 11:24
  • 1
    @Ama, I've tested that before using .net benchmark and found that a loss of performance DID happen even when no exception was fired. Maybe I'm wrong -- is there documentation anywhere about it? I like your sense of fairness :) – bboyle1234 Aug 24 '20 at 04:49
  • 1
    I did not find any official documentation, but there is a whole debate here: https://stackoverflow.com/questions/1308432/do-try-catch-blocks-hurt-performance-when-exceptions-are-not-thrown. In short, it looks like only JIT optimizations might in some cases by impacted by Try Catch blocks, and these optimizations are usually minor. – Ama Aug 28 '20 at 09:54
  • It might be 2 years later, but notifications brought me back. There is a performance penalty from wrapping _every single method call_ in a try-catch, but if no exception is ever thrown, that penalty is negligible. The real problem is readability and maintainability. Writing try-catches everywhere will kill productivity due to every method call being 90% boilerplate try-catch code, and anyone else coming along to read the code will find a tangled mess of exception handlers that have nothing to do with the core logic. Try-catch calls that need it, but try-catching _everything_ is code smell. – Abion47 Mar 22 '22 at 13:32