CLR 如何在底层优化布尔比较操作?

问题描述 投票:0回答:1
注意:我在本问题中使用 PowerShell 作为示例,但这同样适用于任何 .NET 语言。


在 .NET CLR 中,我很想知道评估布尔逻辑的不同方法在幕后是如何工作的。

  • 在考虑实际应用和用例时(即使是极其长时间运行的循环),速度差异可以忽略不计,以至于“无关紧要”,这减少了布尔考虑,只需选择编码标准/格式。
  • “哪个布尔比较运算符更快?”这不是这个问题的目的。



一般来说(我并不是要求提供每种现代 CPU 架构的机器语言指令集的完整列表),.NET CLR 如何“优化”这些布尔比较中的每一个,并且最终,CPU 是否使用不同的指令集?评估这些看似相同的比较的说明?

  • 评估
    == TRUE
    • -eq $true
      vs
      -ne $false
  • 评估
    == FALSE
    • (-not (<statement>))
      vs
      -eq $false
      vs
      -ne $true
  • 假设每次比较仅限于(保证的)布尔结果,并且为了简单说明,我们忽略 $null。
  • 历史背景加分
.net powershell boolean clr compiler-optimization
1个回答
0
投票

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) ...
      
© www.soinside.com 2019 - 2024. All rights reserved.