3

编辑:我基于一个错误的假设提出了这个问题——我正在做的泛型类型实例查找将与在运行时创建的泛型类型上完成的工作相同。编译器可以访问我的工具中的那些,因此它可以将它们编译为地址查找。我仍然对 .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;
}
4

2 回答 2

4

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

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

注意硬编码的地址。

于 2010-11-25T16:47:56.417 回答
2

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

于 2010-11-25T15:21:08.673 回答