【问题标题】:performance of IDictionary<Type, object> vs generic Type propertyIDictionary<Type, object> 与泛型 Type 属性的性能
【发布时间】:2010-11-25 15:10:55
【问题描述】:

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

【问题讨论】:

    标签: .net performance generics hashtable micro-optimization


    【解决方案1】:

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

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

    注意硬编码的地址。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 如果我在运行时使用 typeof(Lookup).MakeGenericType(typeof(string)) 怎么办(我确实尝试过)
      • 想我已经知道了 - 如果我愿意,我可以在运行时创建它,但是如果不使用我的类型的反射,我就无法到达 .o,这很慢。如果你想访问 .o.,你必须告诉编译器泛型类型。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      相关资源
      最近更新 更多