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

时间:2010-11-24 15:20:32

标签: vb.net performance cil

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

If x > y Then x Else y

VS

If x > y Then
    x
Else
    y
End If

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

原来,当您使用If运算符获得相同的功能时,就像这样......

If(x > y, x, y)

生成的MSIL更小,看起来效率更高。这让我想到了这个问题。

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

3 个答案:

答案 0 :(得分:1)

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

对于启动器,您的MSIL不是直接在机器上运行,而是在运行时将JIT编译为实际的机器代码,并在此过程中进行进一步的优化。

此外,代码的性质也有所不同 - 执行简单算术运算的一段代码可能比具有大量分支的较短位代码运行得更快,因为处理器可能会错误预测分支,从而导致管道停滞并放慢了程序。

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

答案 1 :(得分:1)

就原始执行时间而言(不包括加载和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.
    }
}

因此,更长的时间并不一定意味着更慢,尽管Just-In-Time编译器可能需要更长的时间来编译代码,如果代码不在内存中,则加载代码可能需要更长的时间。 / p>

判断两种选择中哪一种更快的唯一方法是衡量。而且大多数时候,无论如何都无所谓。

答案 2 :(得分:1)

没有。一个典型的反例是循环展开,它以尺寸为代价获得速度。