c# – 为什么IF和条件运算符之间的IL有这么大差异?

前端之家收集整理的这篇文章主要介绍了c# – 为什么IF和条件运算符之间的IL有这么大差异?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
C#有一个 conditional operator和IF语句,我怀疑条件运算符只是语法糖.因此在编译时它将与IF操作相同.

然而,他们没有(见下文),他们确实有不同的IL.试图绕过它我的假设是这是条件运算符获得的性能优化,因为它的范围有限.

想知道我的假设是否正确,也许还有更多的假设?

同样在IF的IL中,有一些围绕int值的检查(L_000c,L_000d,L_000f),我无法弄清楚其含义.这使我认为这是一个更强大的解决方案,但由于IF范围更广,性能成本.

IF代码

var result = "";
if (Environment.Is64BitOperatingSystem)
{
    result = "Yes";
}
else
{
    result = "No";
}
Console.WriteLine(result);

条件运算符的代码(我意识到差异,但无论我如何改变它 – 分配给变量等……它几乎没有区别)

Console.WriteLine("Is the OS x64? {0}",Environment.Is64BitOperatingSystem ? "Yes" : "No");

IL为IF

L_0001: ldstr ""
L_0006: stloc.0 
L_0007: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
L_000c: ldc.i4.0 
L_000d: ceq 
L_000f: stloc.2 
L_0010: ldloc.2 
L_0011: brtrue.s L_001d
L_0013: nop 
L_0014: ldstr "Yes"
L_0019: stloc.0 
L_001a: nop 
L_001b: br.s L_0025
L_001d: nop 
L_001e: ldstr "No"
L_0023: stloc.0 
L_0024: nop 
L_0025: ldloc.0 
L_0026: call void [mscorlib]System.Console::WriteLine(string)

IL为条件

L_002c: ldstr "Is the OS x64? {0}"
L_0031: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
L_0036: brtrue.s L_003f
L_0038: ldstr "No"
L_003d: br.s L_0044
L_003f: ldstr "Yes"
L_0044: call void [mscorlib]System.Console::WriteLine(string,object)

解决方法

如果
IL_0000:  call       bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
IL_0005:  brfalse.s  IL_000f
IL_0007:  ldstr      "Yes"
IL_000c:  stloc.0                  // <------ Difference 1
IL_000d:  br.s       IL_0015
IL_000f:  ldstr      "No"
IL_0014:  stloc.0
IL_0015:  ldloc.0
IL_0016:  call       void [mscorlib]System.Console::WriteLine(string)

? (三元操作符)

IL_001b:  call       bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
IL_0020:  brtrue.s   IL_0029
IL_0022:  ldstr      "No"          // <------ Difference 2
IL_0027:  br.s       IL_002e
IL_0029:  ldstr      "Yes"
IL_002e:  stloc.0
IL_002f:  ldloc.0
IL_0030:  call       void [mscorlib]System.Console::WriteLine(string)

(几乎)在发布模式下的相同代码. if添加了第二个未被编译器优化的stdloc.0.而另一个区别是真假都是倒置的.

(所以我知道我应该总是激活WinMerge!)

这将是一个有趣的问题.他们为什么倒?有什么逻辑吗?

猜你在找的C#相关文章