簡體   English   中英

檢查List是否為空合並運算符的性能 <T> 一片空白

[英]Performance of null coalescing operator when checking if List<T> is null

我有一個List<int> ,它從一種方法獲取其值

List<int> items = GetIntegerStuff();

因此當前避免NullReference異常的代碼如下所示

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

我將其更改為該代碼是因為我喜歡短代碼-但我的高級開發人員說,這很不好,因為如果有項目(發生在所有請求的90%左右),則會分配整個列表,這對性能不利。 這是真的?

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

在使用方式上,兩者在性能方面完全相同,因為它們可以編譯為完全相同的東西。

測試代碼:

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

這些是可能的方法:

//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>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM