Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Fun With the ?? Operator in C#: if { } or ?? – Which is Faster?

Posted by Keith Elder | Posted in C# | Posted on 06-08-2009

Yesterday evening at work a team member and I were pair programming.  We had a disagreement about how to code a few lines.  The question was around whether to use the ?? operator or to use an if statement using String.IsNullOrEmpty.  We settled it like most developers do and that is with a benchmark.  Here’s the fun we had.

To give you an idea as to what we were doing here’s some context.  We had a function that took an object.  We wanted to add extra context data to the object, but only if the object didn’t have it set.  In other words, the data may have already been set somewhere else in the application and we didn’t want to override what was already set.  There were two ways to do this and since I was typing I started typing the following.

   1: private void AddContextData(LogEntry entry)

   2: {

   3:     entry.Url = entry.Url ?? HttpContext.Current.Request.Url.ToString();

   4:     entry.UserIpAddress = entry.UserIpAddress ?? HttpContext.Current.Request.UserHostAddress;

   5:     entry.UserName = entry.UserName ?? HttpContext.Current.User.Identity.Name;

   6: }

My pairing partner started in on me immediately.  He was thinking it should be written like this.

   1: private void AddContextData(LogEntry entry)

   2: {

   3:     if (String.IsNullOrEmpty(entry.Url)) entry.Url = Context.Current.Request.Url.ToString();

   4:     if (String.IsNullOrEmpty(entry.UserIpAddress)) entry.UserIpAddress = HttpContext.Current.Request.UserHostAddress;

   5:     if (String.IsNullOrEmpty(entry.UserName)) = entry.UserName = HttpContext.Current.User.Identity.Name;

   6: }

The ?? for those that aren’t familiar with it is called the “null coalescing” operator. Scott Gu wrote about it late 2007 if you want some additional information and samples.  It is a fun little operator and can save you a lot of typing in more places than you think.  Most developers though don’t think to use it and instead code the long handed version doing a check using a if block. 

In the end we decided to settle our disagreement and go with the one that was the fastest.  Thus we whipped up a quick benchmark to test one vs. the other.  Here’s the benchmark code for both samples.

?? Operator Benchmark Code

   1: string x = "foo bar";

   2: Stopwatch watch = new Stopwatch();

   3: long ticks = watch.Time(() => x = x ?? "bar foo", 100000);

   4: textBox1.Text += "??: " + ticks.ToString() + Environment.NewLine;

 

Note: If you copy the above code, it will not work on your machine unless you have a Time() extension method as part of your arsenal. 

if { } Benchmark Code

   1: string x = "foo bar";

   2: Stopwatch watch = new Stopwatch();

   3: long ticks = watch.Time(() =>

   4:                             {

   5:                                 if (String.IsNullOrEmpty(x))

   6:                                 {

   7:                                     x = "bar";

   8:                                 }

   9:                             }

  10:                 , 100000);

  11: textBox1.Text += "if: " + ticks.ToString() + Environment.NewLine;

The Results

The results were not all that exciting. Really it only proved there was wasn’t any difference in speed, if anything giving a very very slight edge to the ?? operator.  At any rate it was a fun side bar to end the evening.  Happy null coalescing!

image

Comments (7)

I agree with NotMyself and Craig on this one as well. Depending on the symantics you are giving to strings and their meaning.

In this case you are saying that string.Empty is a valid value and thus to test it you need to test against if(s==null) {} .

$0.02

No, not bad. Simply a bad comparison. Since string.IsNullOrEmpty does not equate to the coalescing operator ??, then the comparison of the two methods is flawed. It should be compared with if(s == null) {stuff…}

You guys are assuming that string.empty is a bad thing in this case. If it is set, then that is what the developer wanted in that case.

You forgot about the guy who wrote about it here
geekswithblogs.net/…/120462.aspx

and Here

geekswithblogs.net/…/120885.aspx

the last one is interesting because it shows the breakdown of how the ?? operator gets used in IL

I have to agree with NotMyself though, string.empty is not being handled and your making an assumption that someone wouldn’t set the value to string.Empty at any point before getting to your code.

Trinary:Ternary
Tomato:Tomato
Wrong:Correct

8)

“the data may have already been set somewhere else in the application and we didn’t want to override what was already set”

Sounds to me like you are making an assumption that code somewhere else is not setting the values to an empty string. Good lord man at least put a debug.assert in there to confirm your assumptions… 😉

@NotMySelf

In the context where this is used the values are null by default.

Keep your ternary to yourself! 🙂

Hi Keith,

Wouldn’t your coworkers method be technically better because it explicitly handles empty string?

What if in your test string x == “”?

I humbly suggest the Trinary operator.. 8)

entry.Url = String.IsNullOrEmpty(entry.Url) ? Context.Current.Request.Url.ToString() : entry.Url;

Write a comment