c# – 为什么IF和条件运算符之间的IL有这么大差异?
发布时间:2020-12-15 08:10:15 所属栏目:百科 来源:网络整理
导读:C#有一个 conditional operator和IF语句,我怀疑条件运算符只是语法糖.因此在编译时它将与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!) 这将是一个有趣的问题.他们为什么倒?有什么逻辑吗? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |