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!)
这将是一个有趣的问题.他们为什么倒?有什么逻辑吗?