为什么 IF 和条件运算符之间的 IL 存在如此大的差异?
C# 有一个 条件运算符 和 IF 语句,我怀疑条件运算符只是语法糖。所以在编译时它会有一个与 IF 操作相同的操作。
然而它们没有(见下文),它们确实有不同的 IL。尝试着理解它,我的假设是,这是条件运算符获得的性能优化,因为它的范围有限。
想知道我的假设是否正确,也许还有更多内容?
另外,在 IF 的 IL 中,还有一些围绕 int 值的检查(L_000c、L_000d、L_000f),我无法弄清楚其含义。这让我认为这是一个更强大的解决方案,但由于 IF 范围更大而以性能为代价。
Code for 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 for 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 for Conditional
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)
C# has a conditional operator and IF statements and I suspected that the conditional operator would be just syntactic sugar. So at compile time it would have a the same as an IF operation.
However they do not (see below), they do have different IL. Trying to wrap my head around it and the assumption I have is that this is a performance optimisation that the conditional operator gets because it's limited scope.
Would like to know if my assumption is correct or not and maybe if there is more to this?
Also in the IF's IL there is some checks (L_000c, L_000d, L_000f) around int values which I can't figure out the meaning. This is what has lead me to think this is a more robust solution, at the cost of performance because of IF greater scope.
Code for IF
var result = "";
if (Environment.Is64BitOperatingSystem)
{
result = "Yes";
}
else
{
result = "No";
}
Console.WriteLine(result);
Code for conditional operator (I realise differences, but no matter how I change it - assign to variable etc... it makes very little difference)
Console.WriteLine("Is the OS x64? {0}", Environment.Is64BitOperatingSystem ? "Yes" : "No");
IL for 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 for Conditional
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果
? (三元运算符)
在发布模式下两者的代码几乎相同。
if
添加了第二个stdloc.0
,编译器未对其进行优化。另一个区别是true
和false
是相反的。(所以我知道我应该始终启动 WinMerge!)
这将是一个有趣的问题。为什么它们是倒置的?有什么逻辑吗?
if
? (ternary operator)
(nearly)same code for both in release mode. The
if
adds a secondstdloc.0
that isn't optimized away by the compiler. And the other difference is that thetrue
andfalse
are inverted.(so I learn that I should ALWAYS fire up WinMerge!)
And THIS would be an interesting question. Why are they inverted? Is there any logic?