是否有任何优化由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
等类型的性能至少相当于普通的比较器。comparer.GetHashCode(TKey key)
的调用将有效地替换为JIT时的整数值。 这些假设是否正确?