IDictionary <type,object =“”> vs generic类型属性</type,>的性能

时间:2010-11-25 15:10:56

标签: .net performance generics hashtable micro-optimization

编辑:我基于一个错误的假设来建立这个问题 - 我正在做的泛型类型实例查找与在运行时创建的泛型类型上完成的操作相同。我的线束中的那些可供编译器访问,因此它可以将它们编译为地址查找。我仍然对.MakeGenericType在幕后做什么感兴趣。

我刚刚在从IDictionary获取值和从泛型类型获取静态属性的值之间进行了快速比较。

100000000次查找的结果:

字典:14.5246952 通用类型:00.2513280

.NET在后台使用什么样的魔法来快速映射到Generic实例?我会想到类似于哈希表的东西必须用于查找。也许它会被JITTED ......我不知道!你呢?

这是我的测试工具 - 我确定它充满了错误,所以让我知道需要修复的东西!

void Main()
{
    var sw = new Stopwatch();
    var d = new Dictionary<Type, object>() 
    { 
     { typeof(string), new object() },
     { typeof(int), new object() } 

    };
    var stringType = typeof(string);
    var intType = typeof(int);
    sw.Start();
    for (var i = 0; i < 100000000; i++)
    {
        Debug.Assert(d[stringType] != d[intType]);
    }
    sw.Stop();
    sw.Elapsed.Dump();
    sw.Reset();

    Lookup<string>.o = new object();
    Lookup<int>.o = new object();
    sw.Start();
    for (var i = 0; i < 100000000; i++)
    {
        Debug.Assert(Lookup<string>.o != Lookup<int>.o);
    }
    sw.Stop();
    sw.Elapsed.Dump();
}

class Lookup<T>
{
    public static object o;
}

2 个答案:

答案 0 :(得分:4)

JIT编译器知道static o变量的地址。它在加载器堆中分配它。它是泛型类的成员是不相关的。换句话说,解析静态变量的地址不需要运行时查找,它在编译时完成。生成的机器代码很简单:

000000f8  mov         eax,dword ptr ds:[02785D0Ch] 
000000fd  cmp         eax,dword ptr ds:[02785D10h] 

请注意硬编码地址。

答案 1 :(得分:2)

我认为你的泛型的映射是在编译时进行的,而字典在运行时执行查找。