C# 带有'的局部变量声明;是';关键词VS';as';关键词性能差异
在上面的代码中,局部变量是用'is'关键字声明的,但是'as'关键字在性能上有什么不同吗 我想知道是否存在与强制转换和空检查相关的性能差异。(除了str1和str2变量的局部范围差异外)此代码更好:C# 带有'的局部变量声明;是';关键词VS';as';关键词性能差异,c#,performance,keyword,C#,Performance,Keyword,在上面的代码中,局部变量是用'is'关键字声明的,但是'as'关键字在性能上有什么不同吗 我想知道是否存在与强制转换和空检查相关的性能差异。(除了str1和str2变量的局部范围差异外)此代码更好: object obj = "Hello"; // is keyword if (obj is string str1) { Console.WriteLine(str1); } // as keyword string str2 = obj as string; if
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);
}
CLR对此进行了一次检查,而第一个进行了两次检查,第一次使用is运算符,第二次使用类型转换,这显然是一种开销。两个代码示例完全相同;我们可以通过查看IL来测试这一点,IL可以通过多种方式实现,但对于临时事务来说,最方便的方式是 考虑:
使用系统;
公共C类{
object obj=“你好”;
public void ViaIsWithCapture()
{
//is关键字
if(obj是字符串str1)
{
控制台写入线(str1);
}
}
公共无效测试()
{
//as关键字
字符串str2=obj作为字符串;
如果(str2!=null)
{
控制台写入线(str2);
}
}
}
我们可以通过sharplab.io运行此功能,如果您看到右侧,两个版本的IL都是相同的:
vs
很确定它们编译到同一个IL。您可以尝试在sharplab.io上编译它。谢谢您的回答。这是一个很好的工具。当比较IL时,结果是完全相同的。旁注:即使这在这里不重要,你应该更喜欢
is object
而不是!=null
-区别在于!=null
可以调用自定义相等/转换运算符,这比简单的null测试开销更大;is object
语法从不调用运算符;在这种情况下,两个版本完全相同-在此处比较IL:
string str2 = obj as string;
if (str2 != null)
{
Console.WriteLine(str2);
}
.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