代码之家  ›  专栏  ›  技术社区  ›  mcintyre321

IDictionary<Type,object>vs泛型类型属性的性能

  •  3
  • mcintyre321  · 技术社区  · 14 年前

    编辑 :我基于一个错误的假设提出这个问题——我正在进行的泛型类型实例查找与在运行时创建的泛型类型上的查找相同。编译器可以访问我的工具中的那些,因此它可以将它们编译成地址查找。我仍然对makegenericype在幕后做什么很感兴趣。

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

    100000000次查找的结果:

    字典:14.5246952 通用类型:00.2513280

    .NET在后台使用了什么样的魔法来如此快速地映射到泛型的实例?我本以为类似哈希表的东西必须用于查找。可能会紧张。。。我不知道!你…吗?

    这是我的测试马具——我确信它充满了错误,所以让我知道需要修理的东西!

    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 回复  |  直到 14 年前
        1
  •  2
  •   alpha-mouse    14 年前

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

        2
  •  4
  •   Hans Passant    14 年前

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

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

    注意硬编码地址。