I have a field of a nullable type with a value other than null
. Which of the methods below is the fastest, in theory:
Null conditional member access
ThisCantBeNull?.SomeMember
Cast to non-nullable
((MyType)ThisCantBeNull).SomeMember
Use of the Value
member of nullable types
ThisCantBeNull.Value.SomeMember
Note that this is only a theoretical question, such minor differences do not matter, I'm only interested in how the language works and what goes on in the background.
Since you've already checked for null elsewhere, just get the Value
, your third option.
The other two options include an extra check.
But, as noted in the comments, the performance improvement is probably minimal.
Just for curiosity:
public struct MyType
{
public int SomeMember { get; set; }
}
Some very raw tests, disabling compiler optimizations :
MyType? thisCantBeNull = new MyType();
MyType someDefaultValue = new MyType();
var t1 = new Action(() => { var r = (thisCantBeNull ?? someDefaultValue).SomeMember; });
var t2 = new Action(() => { var r = ((MyType)thisCantBeNull).SomeMember; });
var t3 = new Action(() => { var r = thisCantBeNull.Value.SomeMember; });
var t4 = new Action(() => { var r = thisCantBeNull.GetValueOrDefault().SomeMember; });
const int times = 1000 * 1000 * 1000;
var r1 = t1.RunNTimes(times);
// Elapsed Timespan = 00:00:14.45115
var r2 = t2.RunNTimes(times);
// Elapsed Timespan = 00:00:07.9415388
var r3 = t3.RunNTimes(times);
// Elapsed Timespan = 00:00:08.0096765
var r4 = t4.RunNTimes(times);
// Elapsed Timespan = 00:00:07.4732878
The same tests, enabling compiler optimizations :
var r1 = t1.RunNTimes(times);
// Elapsed Timespan = 00:00:02.9142143
var r2 = t2.RunNTimes(times);
// Elapsed Timespan = 00:00:02.4417182
var r3 = t3.RunNTimes(times);
// Elapsed Timespan = 00:00:02.6278304
var r4 = t4.RunNTimes(times);
// Elapsed Timespan = 00:00:02.1725020
Where RunNTimes
is:
public static TimeSpan RunNTimes(this Action a, int nTimes = 1)
{
if (nTimes == 0)
throw new ArgumentException("0 times not allowed", nameof(nTimes));
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < nTimes; ++i)
a();
stopwatch.Stop();
return stopwatch.Elapsed;;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.