在 .NET CLR 中,我很想知道评估布尔逻辑的不同方法在幕后是如何工作的。
一般来说(我并不是要求提供每种现代 CPU 架构的机器语言指令集的完整列表),.NET CLR 如何“优化”这些布尔比较中的每一个,并且最终,CPU 是否使用不同的指令集?评估这些看似相同的比较的说明?
== TRUE
:
-eq $true
vs -ne $false
== FALSE
:
(-not (<statement>))
vs -eq $false
vs -ne $true
Charlieface提供了关键指针:
sharplab.io 是一个很棒的网站,可让您根据 IL(或 JIT ASM)
检查给定的 C# / F# / Visual Basic 代码片段编译成什么内容。使用它,您可以根据以下 C# 代码观察到以下内容:
public class C {
bool b = false;
int dummy = 0;
public void M() {
// equivalent positive tests
if(b) { ++dummy; }
if(b == true) { ++dummy; }
if(b != false) { ++dummy; }
// equivalent negative tests
if(!b) { ++dummy; }
if(b == false) { ++dummy; }
if(b != true) { ++dummy; }
}
}
等效的积极测试确实编译为非常相同的IL代码(原则上,摘要如下):
ldarg.0
ldfld bool C::b
brfalse.s <target-statement>
同样,等效的阴性测试all编译为:
ldarg.0
ldfld bool C::b
brtrue.s <target-statement>
顺便说一句:注意逻辑是如何颠倒的:测试(有效)
true
会产生一个brfalse.s
指令,即如果测试结果不为真,则跳转到哪里,反之亦然(brtrue.s
)
)
亲自试验结果:
使用此链接。
通过右侧窗格中的
Results
下拉列表,您还可以要求将您的输入代码反编译为C#(无论原始输入语言是什么),这证实了上述发现:
等效的positive测试all反编译为:
if (b) ...
等效的否定测试all反编译为:
if (!b) ...