0

We know that the use of the Null Coalescing Operator

MyObj obj = differntObj ?? new MyObj();

is equivalent to the following:

MyObj obj;
if (differntObj != null){
    obj = differntObj;
}
else {
    obj = new MyObj();
}

My Question: Is the Null Coalescing Operator faster than implementing the logic your self like in the second code snippet? If not, is there any advantages outside of less keystrokes why one would use the Null Coalescing Operator?

Cabbage Champion
  • 1,193
  • 1
  • 6
  • 21
  • 3
    Is less keystrokes not enough? – Blorgbeard Aug 02 '19 at 22:57
  • Its brevity also makes it quicker to understand what's going on. At least for me. I maintain other peoples' code all the time and readability/clarity is key. – itsme86 Aug 02 '19 at 23:12
  • 3
    Also https://ericlippert.com/2012/12/17/performance-rant/ – itsme86 Aug 02 '19 at 23:14
  • 2
    You may find this one helpful - https://stackoverflow.com/a/13385694/8398997 – ANaik Aug 02 '19 at 23:23
  • 1
    I guess the spirit of this question is admirable enough, however when it comes to micro-optimizations the world is not what it seems. The compiler and the jitter are complicated, whats faster in one case is not always in another situation.Even the example you have given would result in a different slightly compilation in certain cases. The first thing to do is work towards readability and maintainability, then if you need heavy optimization then you go and get your trusty benchmarker and go to town – TheGeneral Aug 02 '19 at 23:31

1 Answers1

1

When you compile them and look at the generated IL, you'll see more instructions and allocations in the second example, but that doesn't necessarily mean it will take longer. And even if it did, NO ONE will ever notice.

Don’t over-focus on speed metrics; look at the big picture Focus on readable code, like good variable names and consistent style. Use whichever style you find more readable and maintainable.

For what it's worth, here's the IL generated from the two samples:

Code:

MyObj obj2 = differentObj ?? new MyObj();

IL:

.maxstack 2
.locals init (
    [0] class Test.MyObj
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: brtrue.s IL_000b
IL_0005: pop
IL_0006: newobj instance void Test.MyObj::.ctor()
IL_000b: stloc.0

Code:

MyObj obj;
if (differentObj != null) obj = differentObj;
else obj = new MyObj();

IL:

.maxstack 2
.locals init (
    [0] class Test.MyObj,
    [1] bool
)

IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: cgt.un
IL_0005: stloc.1
IL_0006: ldloc.1
IL_0007: brfalse.s IL_000d
IL_0009: ldarg.0
IL_000a: stloc.0
IL_000b: br.s IL_0013
IL_000d: newobj instance void Test.MyObj::.ctor()
IL_0012: stloc.0
Rufus L
  • 36,127
  • 5
  • 30
  • 43