объявление локальной переменной с ключевым словом 'is' VS 'as' разница в производительности ключевого слова - PullRequest
3 голосов
/ 12 июля 2020
object obj = "Hello";

// is keyword
if (obj is string str1)
{
   Console.WriteLine(str1);
}

// as keyword
string str2 = obj as string;
if (str2 != null)
{
   Console.WriteLine(str2);
}

В приведенном выше коде локальная переменная объявлена ​​с ключевым словом 'is', но есть ли разница в производительности с ключевым словом 'as'?

Интересно, есть ли производительность разница, связанная с приведением типов и проверкой нуля. (Помимо различий в локальной области видимости переменных str1 и str2)

Ответы [ 2 ]

2 голосов
/ 12 июля 2020

Два образца кода абсолютно идентичны на 100%; мы можем проверить это, посмотрев на IL, что можно сделать разными способами, но наиболее удобным для ad-ho c вещей является https://sharplab.io/

Рассмотрим:

using System;
public class C {
    object obj = "Hello";
    public void ViaIsWithCapture()
    {
        // is keyword
        if (obj is string str1)
        {
           Console.WriteLine(str1);
        }
    }
    public void ViaAsThenNullTest()
    {
        // as keyword
        string str2 = obj as string;
        if (str2 != null)
        {
           Console.WriteLine(str2);
        }
    }
}

Мы можем запустить это через sharplab.io вот так , и если вы посмотрите справа, IL для обеих версий работает идентично :

    .method public hidebysig 
        instance void ViaIsWithCapture () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 22 (0x16)
        .maxstack 1
        .locals init (
            [0] string str1
        )

        IL_0000: ldarg.0
        IL_0001: ldfld object C::obj
        IL_0006: isinst [System.Private.CoreLib]System.String
        IL_000b: stloc.0
        IL_000c: ldloc.0
        IL_000d: brfalse.s IL_0015

        IL_000f: ldloc.0
        IL_0010: call void [System.Console]System.Console::WriteLine(string)

        IL_0015: ret
    } // end of method C::ViaIsWithCapture

против

    .method public hidebysig 
        instance void ViaAsThenNullTest () cil managed 
    {
        // Method begins at RVA 0x2074
        // Code size 22 (0x16)
        .maxstack 1
        .locals init (
            [0] string str2
        )

        IL_0000: ldarg.0
        IL_0001: ldfld object C::obj
        IL_0006: isinst [System.Private.CoreLib]System.String
        IL_000b: stloc.0
        IL_000c: ldloc.0
        IL_000d: brfalse.s IL_0015

        IL_000f: ldloc.0
        IL_0010: call void [System.Console]System.Console::WriteLine(string)

        IL_0015: ret
    } // end of method C::ViaAsThenNullTest
0 голосов
/ 12 июля 2020

Этот код лучше:

string str2 = obj as string;
if (str2 != null)
  {
    Console.WriteLine(str2);
  }

CLR проверяет это один раз, а первый - два раза, сначала с помощью оператора IS, а затем при приведении типов, что, очевидно, является накладными расходами.

...