检查List <t>是否为null时,空合并运算符的性能

时间:2018-07-16 13:42:40

标签: c#

我有一个List<int>,它从方法中获取值

List<int> items = GetIntegerStuff();

因此避免NullReference异常的当前代码如下:

if (items == null)
{
    items = new List<int>();
}

我已将其更改为此代码,因为我喜欢短代码-但是我的高级开发人员说,这很不好,因为如果有项目(发生在所有请求的90%左右),则会分配整个列表,这对性能。这是真的吗?

items = items ?? new List<int>();

2 个答案:

答案 0 :(得分:3)

在使用方式上,两者在性能方面完全相同,因为它们编译为完全相同的东西。

测试代码:

static void NullCoalescing(List<int> a)
{
    a = a ?? new List<int>();
    Console.WriteLine(a);
}
static void IfStatement(List<int> a)
{
    if(a == null) a = new List<int>();
    Console.WriteLine(a);
}

编译为:

C.NullCoalescing(System.Collections.Generic.List`1<Int32>)
    L0000: push rsi
    L0001: sub rsp, 0x20
    L0005: test rcx, rcx
    L0008: jnz L0044
    L000a: mov rcx, 0x7ffb92892a78
    L0014: call 0x7ffb94712540
    L0019: mov rsi, rax
    L001c: mov ecx, 0x1
    L0021: mov edx, 0x43
    L0026: call 0x7ffb9487ff10
    L002b: mov rdx, 0x2966e0ddef8
    L0035: mov rdx, [rdx]
    L0038: lea rcx, [rsi+0x8]
    L003c: call 0x7ffb94713e70
    L0041: mov rcx, rsi
    L0044: call System.Console.WriteLine(System.Object)
    L0049: nop
    L004a: add rsp, 0x20
    L004e: pop rsi
    L004f: ret

C.IfStatement(System.Collections.Generic.List`1<Int32>)
    L0000: push rsi
    L0001: sub rsp, 0x20
    L0005: test rcx, rcx
    L0008: jnz L0044
    L000a: mov rcx, 0x7ffb92892a78
    L0014: call 0x7ffb94712540
    L0019: mov rsi, rax
    L001c: mov ecx, 0x1
    L0021: mov edx, 0x43
    L0026: call 0x7ffb9487ff10
    L002b: mov rdx, 0x2966e0ddef8
    L0035: mov rdx, [rdx]
    L0038: lea rcx, [rsi+0x8]
    L003c: call 0x7ffb94713e70
    L0041: mov rcx, rsi
    L0044: call System.Console.WriteLine(System.Object)
    L0049: nop
    L004a: add rsp, 0x20
    L004e: pop rsi
    L004f: ret

如您所见,它们的编译完全相同。

在这里查看:

https://sharplab.io/#v2:EYLgHgbALANALiAhgZwLYB8ACAGABJgRgG4BYAKB3wKlIoGZ8AmXAYVwG9zzceqJ8ouAHIBXADZiWAe0RiApsgDGASwB2AcwAUAGWXI4AHjVwAfLkQBKbr05le987gC8jgPyvcquQHdcu/UaqppoWtA68hACcmpZhvAC+1jyE/JiCAJIAZgDKcIhwcqhyQTp6hsZmlkkc1fbKmTHOLqriYhaOzT5+ZYHBobURBNGx1Ylk8UA

答案 1 :(得分:1)

这些是可能的方法:

//APPROACH 1
List<int> items = GetIntegerStuff();
if (items == null)
{
    items = new List<int>();
}

//APPROACH 2
List<int> items = GetIntegerStuff() ?? new List<int>();

//APPROACH 3
List<int> items = GetIntegerStuff();
items = items ?? new List<int>();

//APPROACH 4
List<int> items = GetIntegerStuff();
items = items == null ? new List<int>() : items;

我会选择数字2,从我的角度来看,这是最干净的。


仅出于完整性考虑,在某些情况下您可以找到类似的内容:

class Program
{
    private static List<int> _items = new List<int>();

    private static List<int> Items
    {
        get
        {
            return _items;
        }

        set
        {
            _items = value ?? new List<int>();
        }
    }

    static void Main(string[] args)
    {
        //APPROACH 5
        Items = GetIntegerStuff();
    }

    private static Random Random = new Random();
    private static List<int> GetIntegerStuff()
    {
        switch (Random.Next(0, 2))
        {
            case 0:
                return null;
                break;
            default:
                return new List<int>();
                break;
        }
    }
}

这对性能不利吗?

List<int> items = GetIntegerStuff();
items = items ?? new List<int>();

否,但实际上它会针对以下内容执行更多指令:

List<int> items = GetIntegerStuff();
if (items == null)
{
    items = new List<int>();
}

List<int> items = GetIntegerStuff() ?? new List<int>();