具有值类型键的字典的JIT优化

时间:2013-05-13 07:36:08

标签: c# performance dictionary jit

是否有任何优化由Jitter完成以避免装箱并拒绝根据通用参数是什么而无法取得的代码分支?例如。在Dictionary<int, TValue>使用的默认相等比较器中,比较器实现将是GenericEqualityComparer<int>,据我所知,因为int实现了IEquatable<T>。此比较器的Equals方法如下所示:

public override bool Equals(T x, T y)
{
  if ((object) x != null)
  {
    if ((object) y != null)
      return x.Equals(y);
    else
      return false;
  }
  else
    return (object) y == null;
}

这种方法的jitted版本会是什么样的?在T是值类型的情况下,是否可以将其优化为仅仅有效地比较x和y,并忽略与null的比较?

使用自定义比较器和Equals和GetHashCode()的简单实现,我得到一个比使用默认比较器的字典稍差更差的性能!这可能是随机基准噪音,但差异似乎非常一致。

   public bool Equals(int a, int b) { return a == b; }
   public int GetHashCode(int obj) { return obj; }

更奇怪的是,当我通过重新编译而没有完全比较器字段来创建反向工程的Dictionary类时,通过使用键本身和Equals内联GetHashCode调用来有效地对整数键进行硬编码。 -calls简单平等,性能更差。我对此的唯一解释是:

  • 实现IEquatable<T>的值类型将获得在字典中创建的默认相等比较器,其int等类型的性能至少相当于普通的比较器。
  • 字典完成的GetHashCode / Equals调用从性能角度来看是无关紧要的,或者它们是内联的,因此对comparer.GetHashCode(TKey key)的调用将有效地替换为JIT时的整数值。

这些假设是否正确?

0 个答案:

没有答案