CLR会优化并内联此GetHashCode()吗?

时间:2010-09-08 12:32:57

标签: c# optimization clr inline jit

假设我们有一个这样的值类型,其中字段为readonly并在构造期间初始化:

public struct SomeValue
{
    private readonly Int32 field1;
    private readonly Int32 field2;

    ...
}

另外,假设我们有一个帮助类,它允许我们以可重用的方式为复合类型实现GetHashCode()

public struct SomeValue
{
    ...

    public override Int32 GetHashCode()
    {
        return HashHelpers.GetHashCode(this.field1, this.field2);
    }
}

现在,编译器必须意识到在构造类型之后字段值永远不会改变,因为它们是readonly。因此,当HashHelpers.GetHashCode()被JIT编辑时,是否可能以某种方式内联对SomeValue.GetHashCode()的调用?

4 个答案:

答案 0 :(得分:3)

内联有一些well-known规则(.NET 4可能添加了更多)。在您的情况下,如果HashHelpers.GetHashCode足够简单,它将被内联。我不认为那些只读字段在这种情况下具有任何意义。

答案 1 :(得分:3)

您没有发布HashHelper方法的代码,但由于它应该小而快,是的,它很可能会被内联。

而且,是的,JIT优化器能够在编译时评估表达式,并用简单的常量值替换代码。但是,当您使用 readonly 成员时,情况就不会发生。因为它具有的值由构造函数决定。优化器不会考虑其他方法中的代码来猜测字段是否具有已知值。它必须能够在编译GetHashCode时检测到该值。

如果使用const初始化readonly字段,则可以获得此值。并在GetHashCode实现中使用相同的const。那太难看了。鉴于您从微观优化中获得的收益非常有限,这可能不是您应该考虑的事情。可能的胜利不超过纳秒。但很可能为零,因为优化器会用mov替换xor。

答案 2 :(得分:1)

据我所知,你的字段被声明为readonly的事实与抖动是否决定内联方法无关。

这篇文章讨论了.NET 3.5sp1抖动使用的一些启发式方法。这可能已经在.NET 4中发生了变化,并且在将来的版本中可能会再次发生变化。

答案 3 :(得分:0)

据我所知,对HashHelpers.GetHashCode()的调用不会被内联,它只会被视为对CIL中该方法的正常调用。我可能错了,但我很确定我不是。