12

Does anyone have metrics on performing null test versus wrapping code in a try catch?

I suspect that the null test is much more efficient, but I don't have any empirical data.

The environment is C#/.net 3.x and the code comparison is:

Dude x = (Dude)Session["xxxx"];
x = x== null ? new Dude(): x;

versus

Dude x = null;
try {
    x = (Dude)Session["xxxx"];
    x.something();
} catch {
    x = new Dude();
}

are there any advantages to wrapping in try catch?

mson
  • 7,762
  • 6
  • 40
  • 70

10 Answers10

24

If null is a possible expected value, then test for null. If you don't like the null test and have a default value, you can use the null coelescing operator to set the default value:

// value is (Dude)Session["xxxx"] if not null, otherwise it's a new object.
Dude x = (Dude)Session["xxxx"] ?? new Dude();

Save try/catch for Exceptions (truly unexpected events).

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • in the regular course of events the object should not be null. in this case, null only occurs if the session has timed out – mson Dec 09 '09 at 15:08
  • 2
    +1, NEVER use exceptions for program control flow. The only time you would want to create an exception is if (Dude)Session["xxxx"]; being null was cause to stop the functioning of the method you were in. i.e., if a null value there would prevent that method from successfully accomplishing the function it was called to perform. As you wrote the question, if all you need to do in this case to continue is to create a new Dude(), then that is not the case, so an exception not warranted. – Charles Bretana Dec 09 '09 at 15:18
9

If compact code is what you really looking for you can:

Dude x = Session["xxxx"] as Dude ?? new Dude();

the ?? operator will return the first non-null value of two values if there is any.

Thanks

4

I would think that this would be the fastest route:

Dude x = (Dude)Session["xxxx"] ?? new Dude();

The ?? operator is a shortcut for null checking when you want to assign a specific value if it is null.

Anyway, Exceptions end up not only creating a new object, but having the generate a stack trace, which slows things down.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • 2
    don't cast, use the 'as' keyword (See Mike's comment). invalid casting throws. – Stefan Monov Dec 09 '09 at 15:09
  • @Stefan: I use Java at work, which is probably why I didn't think of the `as` keyword. – Powerlord Dec 09 '09 at 15:12
  • @Stefan: If `Session["xxxx"]` doesn't contain either a `Dude` or `null` then I'd want it to throw! But I suppose it's the OP's call whether they'd want an exception in that situation or whether they'd want to just silently swallow the weirdness and return a brand new `Dude`. – LukeH Dec 09 '09 at 15:28
2

Exceptions do take extra memory, as well as time, to catch. It is ALWAYS better to test for null if it's a possible value.

Nathan Wheeler
  • 5,896
  • 2
  • 29
  • 48
2

Another thing to consider it that it's simply less code and more readable to do the null test. Usually having try/catch blocks adds essentially no overhead to your code for the normal case, but when the exception is triggered it's quite expensive.

Francis Upton IV
  • 19,322
  • 3
  • 53
  • 57
  • +1. Creating the stack trace is probably what is really expensive, a few orders of magnitude above a `null` test. – peterchen Dec 09 '09 at 15:05
0

You should never use a try/catch in the normal code path of your program. If you do you'll create constant garbage which the garbage collector will need to process. Much better to just test for null.

Benj
  • 31,668
  • 17
  • 78
  • 127
  • 1
    how does try/catch create garbage? If you mean the exception object, then this is trivial. – Stefan Monov Dec 09 '09 at 15:08
  • One exception object is trivial, but imagine creating one object per each loop iteration. – Kevin Panko Dec 09 '09 at 15:41
  • Having profiled a server application which generated thousands of such objects every second and was in constant garbage churn I can tell you that it isn't necessarily trivial. Garbage collection cost is one of the things that most people forget when working in Java/C#. – Benj Dec 09 '09 at 15:53
  • Hi, doesn't the setup of the try/catch block more expensive than the exception thrown itself? I mean, I thought the real performance penalty was the setup of the exception monitoring when the execution path was reaching a try/catch block... I may be wrong – Mike Gleason jr Couturier Dec 09 '09 at 21:15
0

Exception should work fine in this case, but I believe number #1 is the best way to go. An exception should not be used as an If/else statement, an exception throws an error, which takes up more system resources than your first comparison.

Pieter888
  • 4,882
  • 13
  • 53
  • 74
0

NEVER use exceptions for program control flow. The only time you would want to create an exception is if (Dude)Session["xxxx"]; being null was cause to stop the functioning of the method you were in. i.e., if a null value there would prevent that method from successfully accomplishing the function it was called to perform. As you wrote the question, if all you need to do in this case to continue is to create a new Dude(), then that is not the case, so an exception not warranted.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
0

Use exceptions for exceptional cases - not normal program flow.

If you're having to do a lot of null checks consider making use of the Null Object Pattern instead of using real nulls to indicate a non-existent value that perhaps has default behaviour.

I was alway a bit suspicious of the Null Object Pattern until I started using Objective-C where it's the built-in behaviour. It really does clean up a lot of code (but it's still not always appropriate, of course).

philsquared
  • 22,403
  • 12
  • 69
  • 98
0

As you only want to check for null, that is what you should do. It's more efficient than catching an exception.

Also, by catching exceptions you should be very specific and only catch exactly what you expect. If you catch any type of exception, you risk catching errors that you didn't anticipate and handle them the wrong way.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005