.net - IDictionary<Type, object> 与通用 Type 属性的性能

标签 .net performance generics hashtable micro-optimization

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

最佳答案

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

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

注意硬编码地址。

关于.net - IDictionary<Type, object> 与通用 Type 属性的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4278472/

相关文章:

c# - 数字和可为空数字之间的加减法的反直觉设计

Sqlite ALTER TABLE - 在现有列之间添加列?

.net - Linq to SQL 是否比 Linq to Entities 更快?

.net - 使用lambda而不是字符串属性名称选择模型属性

scala - 如何定义具有未绑定(bind)类型参数的成员的案例类?

c# - 如何在打开另一个 Winform 时关闭一个 Winform

asp.net - 不引用 MVC 的 AllowHtml 属性

html - 在加载 <IMG> 标记中的所有图像之前,不应加载 ngOnInit 或 ngAfterViewInit 中的内容

java - 如何调用JAVA绑定(bind)的泛型参数化方法?

.net - C# 结构体中的数组