我正在创建一个我正在进行性能测试的库。在其中我生成Dictionary<Type, X>
一次。这些项目目前以随机顺序插入。字典在应用程序生命周期内保持不变。
然后经常用于查找项目。查找是库中较大的瓶颈之一。
是的,我是微观优化,但要学习。我想知道是否有更好的方法来获得查找性能?
更新
我用dotTrace来测量性能。报告+ dotTrace在我的家用电脑中,所以我没有这里的报告(否则可以将其上传到其他地方)。
我使用了这里的测试: https://github.com/danielpalme/IocPerformance
字典定义可在此处找到:https://github.com/jgauffin/Griffin.Container/blob/master/Source/Griffin.Container/ContainerBase.cs
(我上个星期五创建了容器,不要期望太多)
UPDATE2
Dictionary.TryGetValue
总共需要101毫秒的Resolve
(总共251毫秒),如果我正确地解释了这些数字,则为40.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)
内发生的所有事情。