8

We use ?? Operator to evaluate expressions against null values, for example:

string foo = null;
string bar = "woooo";
string foobar= foo ?? bar ; 
// Evaluates foobar as woooo

We also used an if statement, which works the same if used with above expression

string foo = null;
string bar = "woooo";
if(foo==null)
   string foobar=   "woooo" ;
// Evaluates foobar as woooo same as above

And also ?: Ternary Operator...

string foo = null;
string bar = "woooo";    
string foobar= foo==null ? "woooo" : null ;
// Evaluates foobar as woooo same as above

I know that null coalescing is precise in syntax, but which one is compiled faster among both and performs more faster and why?

Mayank Pathak
  • 3,621
  • 5
  • 39
  • 67
  • its more like syntactic sugar .. – Amitd Nov 14 '12 at 19:04
  • 1
    If you're that concerned about runtime, C# might not be your best bet. – Nick Vaccaro Nov 14 '12 at 19:04
  • Technically, you should be comparing `??` to `?:` not to `if` as `?:` is much more a closer logical fit to `??` than `if` is. – James Michael Hare Nov 14 '12 at 19:09
  • 2
    If this is causing a performance problem for you code, you have much bigger concerns. – Servy Nov 14 '12 at 19:12
  • @Servy No, performance wise i found them same..but i was thinking why was the need of the exact alternate..i know its syntactically more precise then if..i just wanted to know the best answer of using the both statement in diff way that's it... – Mayank Pathak Nov 14 '12 at 19:15
  • @MayankPathak You should only concern yourself with the performance of some block of code when you've demonstrated that you are having a problem involving that construct or method. "Premature optimization is the root of all evil." – Servy Nov 14 '12 at 19:23
  • 1
    The second code example is _not_ the same as the first! If `foo` is not `null`, the first example will assign `foo` to `foobar`. Your second example doesn't. – comecme Nov 14 '12 at 19:30
  • 1
    @comecme It's worse then that: `Embedded statement cannot be a declaration or labeled statement` – asawyer Nov 14 '12 at 19:35
  • 2
    Odd that this was closed as "not a real question", seemed like a good question to me. I do think "performance first" is typically the wrong strategy, but it's still a valid question in my book. – James Michael Hare Nov 15 '12 at 15:20
  • possible duplicate of http://stackoverflow.com/questions/1543522/why-do-we-prefer-to-operator-in-c – nawfal Jan 29 '14 at 01:44

2 Answers2

27

You may be asking the wrong question. You don't choose to use one over the other primarily due to efficiency (though it may be a secondary concern), but due to utility.

Really you should compare ?? to ?: and not to if as they have different purposes. Yes, they are all some form of "conditional" goodness, but the key is that both ?? and ?: evaluate to a value, whereas if does not, thus they often have different uses.

For example, the following code:

Console.WriteLine("The order} is for {1} product",
    orderId, productId ?? "every");

Would be clunkier to write with an if:

if (productId == null)
{
    Console.WriteLine("The order {0} is for every product",
        orderId);
}
else
{
    Console.WriteLine("The order {0} is for {1} product",
        orderId, productId);
}

Yes, you could condense to one, but then you'd have a temp variable, etc:

if (productId == null)
{
    productId = "every";
}

Console.WriteLine("The order {0} is for {1} product",
    orderId, productId);

Thus really, you shouldn't compare the two, because they point of the ?? is to evaluate to a value if the argument is null, whereas the point of if is to execute a different path (not directly resulting in a value.

So, a better question may be, why not this instead:

Console.WriteLine("The order {0} is for {1} product",
    orderId, productId == null ? "every" : productId);

Which is much the same (both evaluate to a value) and are not as much for flow control.

So, let's look at the difference. Let's write this code three ways:

// Way 1 with if
string foo = null;
string folder = foo;

if (folder == null)
{
    folder = "bar";
}

// Way 2 with ? :
string foo2 = null;
var folder2 = foo2 != null ? foo2 : "bar";

// Way 3 with ??
string foo3 = null;
var folder3 = foo3 ?? "bar";

For the IF, we get the following IL:

IL_0001:  ldnull      
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  ldnull      
IL_0005:  ceq         
IL_0007:  ldc.i4.0    
IL_0008:  ceq         
IL_000A:  stloc.1     
IL_000B:  ldloc.1     
IL_000C:  brtrue.s    IL_0016
IL_000E:  nop         
IL_000F:  ldstr       "bar"
IL_0014:  stloc.0     

For the conditional (? :) we get the following IL:

IL_0001:  ldnull      
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  brtrue.s    IL_000D
IL_0006:  ldstr       "bar"
IL_000B:  br.s        IL_000E
IL_000D:  ldloc.0     
IL_000E:  nop         
IL_000F:  stloc.1   

For the null-coallescing (??) we get this IL:

IL_0001:  ldnull      
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  dup         
IL_0005:  brtrue.s    IL_000D
IL_0007:  pop         
IL_0008:  ldstr       "bar"
IL_000D:  stloc.1    

Notice how each successive one is simpler? The if is larger IL because it needs branching logic to handle the separate statements. The ?: is smaller because it simply evaluates to a value (not branching to other statements) but still needs to load the operand to compare to (null).

The ?? is the simplest of all, because there is an IL instruction for comparing to null (vs loading null and comparing to it.

SO all of this said, you're talking a very small difference in terms of IL, which may or may not affect performance. Regardless, chances are this will have very little major difference compared to more intensive work in the program (math, database, network, etc.).

Thus, I would suggest choose the one that is the most readable, and only optimize if you find through profiling that your current method is inadequate and a bottleneck.

To me, the real reason to use ?: or ?? is when you want the end result to be a value. That is, anytime you'd be tempted to write:

if (someCondition)
    x = value1;
else 
    x = value2;

Then I'd use the conditional (?:) because that is what it is a great shorthand for. x gets one or the other value based on this condition...

Then I'd go one further with ?? and say the same is true, you want to assign a value to a variable based on the null-ness of an identiifer.

So if is great for flow-control, but if you are just returning one of two values or assigning one of two values based on a condition, I'd use ?: or ?? as appropriate.

Finally keep in mind how these things are implemented under the covers (IL and the associated performance) are subject to change with each revision of the .NET Framework (as of me writing this right now they are all so close to be negligible).

Thus, what may be faster today may not be faster tomorrow. So again, I'd just say go with the one that fits best and you find most readable.

UPDATE

Incidentally, for the truly obsessed, I compared 10,000,000 iterations of each code swatch above, and here's the total time to execute each. Looks like ?? is fastest for me, but again these are so close to be almost inconsequential...

10,000,000 iterations of:
?: took: 489 ms, 4.89E-06 ms/item.
?? took: 458 ms, 4.58E-06 ms/item.
if took: 641 ms, 6.41E-06 ms/item.
James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
6

They should both compile to the same IL, and thus execute the same.

Even if they didn't, the performance difference would be negligible. I wouldn't even think to look at this unless I profiled my application and saw the statements taking a significant amount of time.

Always use the clearest syntax unless you can prove it's causing a performance problem, not before.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536