比Dictionary <type,x =“”>?</type,>更快的替代方案

时间:2012-05-14 07:07:46

标签: c# performance dictionary inversion-of-control

我正在创建一个我正在进行性能测试的库。在其中我生成Dictionary<Type, X>一次。这些项目目前以随机顺序插入。字典在应用程序生命周期内保持不变。

然后经常用于查找项目。查找是库中较大的瓶颈之一。

是的,我是微观优化,但要学习。我想知道是否有更好的方法来获得查找性能?

更新

我用dotTrace来测量性能。报告+ dotTrace在我的家用电脑中,所以我没有这里的报告(否则可以将其上传到其他地方)。

我使用了这里的测试: https://github.com/danielpalme/IocPerformance

字典定义可在此处找到:https://github.com/jgauffin/Griffin.Container/blob/master/Source/Griffin.Container/ContainerBase.cs

(我上个星期五创建了容器,不要期望太多)

UPDATE2

Performance breakdown

Dictionary.TryGetValue总共需要101毫秒的Resolve(总共251毫秒),如果我正确地解释了这些数字,则为40.2%。

2 个答案:

答案 0 :(得分:2)

如果类型是编译时定义的,您可以尝试像这样实现它:

static class ValueFor<T>
{
  // you get another field per type T
  public static X X { get; private set; }

  internal static SetUpValue(X value) { X = value; }
}

只需使用此功能即可访问。

var myIntX = ValueFor<int>.X;

答案 1 :(得分:1)

来自IoC容器的性能基准 Daniel Palme(但其他人也是如此)有点误导,因为基准测试解决了容器中非常浅的对象图(虽然它确实清楚地表明容器之间的性能差异很大)。这是不现实的,因为大多数应用程序(正确使用DI)将具有包含对象剂量的对象图。执行此操作时,只需要解析根对象,并且在正确写入容器时,这意味着在大多数情况下(或者最多只是一个),您只需要对Dictionary<T,V>.TryGetValue每(Web)请求进行一次调用少数)。因此,Dictionary<T, V>的性能并不是真正的问题。

我认为Dictionary<T,V> TKey System.Type的性能成本的最大部分与为给定Type生成哈希码的性能成本有关}。每次拨打TryGetValue时,都必须调用Type.GetHashCode()。 GetHashCode是虚拟的(不能内联),该方法调用3个其他虚拟方法。最后,对RuntimeHelpers.GetHashCode(key)进行静态(外部)调用。

换句话说,您可以优化性能以编写使用Type作为键的特定(非通用)词典类,而不是调用Type.GetHashCode()您应该调用RuntimeHelpers.GetHashCode(key) }。

更新(2013-04-05):

几个月前,我试图提高我维护的DI容器的性能,并且我在优化字典部分。我编写了自己的字典,直接调用RuntimeHelpers.GetHashCode(key)(并跳过了虚拟调用),但最终性能提升到如此之小(在Palme的基准测试中大约1%),我决定恢复这些代码更改。所以我目前的理解是Dictionary<Type, X>实际的性能成本实际上是RuntimeHelpers.GetHashCode(key)内发生的所有事情。