2

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;
}

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

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

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

更奇怪的是,当我通过重新编译它而不完全使用比较器字段来创建一个逆向工程 Dictionary 类时,通过将 GetHashCode 调用与键本身内联,并将 Equals 调用与一个简单的相等性内联,有效地将其硬编码为整数键,性能是更糟。我对此的唯一解释是:

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

这些假设是否正确?

4

0 回答 0