【问题标题】:Does the size of compiled code into MSIL necessarily correlate to code speed?编译成 MSIL 的代码大小是否必然与代码速度相关?
【发布时间】:2010-11-24 15:20:31
【问题描述】:

我一直在使用 Visual Basic 中不同类型的本机代码操作,然后使用 Reflector 检查代码以查看生成的 MSIL 类型。例如,我想知道,在一行 If-Then-Else 不同于 If-Then-Else 拆分为多行,即。

If x > y Then x Else y

对比

If x > y Then
    x
Else
    y
End If

原来这两个编译成相同的 MSIL。然后我想知道新的 If operator,类似于旧的 IIf function。重要的是要注意 IIf 确实是一个函数,因此会产生函数调用的开销,因此虽然它看起来很简洁,但它也有其缺点。此外,它在返回值之前评估 TruePart 和 FalsePart,即。不是短路,所以它可能有意想不到的行为。所以,我会坚持使用 If 运算符

事实证明,当您将 If 运算符用于相同的功能时,就像这样......

If(x > y, x, y)

生产的 MSIL 体积更小,而且看起来效率更高。这让我想到了这个主题的问题。

编译成 MSIL 的代码大小是否必然与代码速度相关?

【问题讨论】:

    标签: vb.net performance cil


    【解决方案1】:

    在非常简单的层面上,执行更多指令将花费更长的时间,但您不能只说编译代码的大小与速度相关。

    首先,您的 MSIL 并非直接在机器上运行,而是会在运行时被 JIT 编译为实际的机器代码,并可能在此过程中进行进一步优化。

    此外,代码的性质也有所不同 - 执行简单算术运算的长代码可能比具有大量分支的较短代码运行得更快,这仅仅是因为处理器可能错误预测分支,从而使管道停止并减慢程序。

    真正确定一段代码是否比另一段更快的唯一方法是运行它并在适当的目标环境中对其进行分析。

    【讨论】:

      【解决方案2】:

      就原始执行时间(不包括加载和 JIT 编译代码的开销)而言,没有相关性。

      循环是可以执行很长时间的紧凑代码的主要示例。你可以写一个永远不会终止的非常短的一行:

      void VerySmallAndNeverTerminates() { for (;;); }
      

      您也可以编写复杂且只要编译器允许(一旦 JIT 编译器完成)几乎立即返回的代码。你只需要比编译器更聪明:

      void VeryBigAndFast(int n) {
          if (Math.Abs(n) < 0) {
              // Write lots of code here. What doesn't matter,
              // since it will never be executed. The compiler
              // probably isn't smart enough to know that.
          }
      }
      

      因此,更长并不一定意味着更慢,尽管即时编译器编译代码可能需要更长的时间,如果代码不在内存中,加载代码可能需要更长的时间。

      判断两种选择中哪一种更快的唯一方法是测量。而且大多数时候,这真的无关紧要。

      【讨论】:

        【解决方案3】:

        没有。一个典型的反例是循环展开,它以大小为代价来提高速度。

        【讨论】:

          猜你喜欢
          • 2010-11-26
          • 1970-01-01
          • 2012-05-05
          • 1970-01-01
          • 1970-01-01
          • 2012-09-22
          • 2011-06-14
          • 1970-01-01
          相关资源
          最近更新 更多