производительность IDictionary‹Type, object› по сравнению с общим свойством Type

изменить: я основал этот вопрос на ложном предположении, что поиск экземпляров универсального типа, который я выполнял, будет выполнять ту же работу, что и при выполнении для универсальных типов, созданных во время выполнения. Те, что есть в моей системе, доступны для компилятора, поэтому он может скомпилировать их для поиска адресов. Мне все еще очень интересно, что .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;
}

person mcintyre321    schedule 25.11.2010    source источник


Ответы (2)


Я думаю, что сопоставление с вашими дженериками выполняется во время компиляции, тогда как словарь выполняет поиск во время выполнения.

person alpha-mouse    schedule 25.11.2010
comment
Как это сделать, если я использую typeof(Lookup‹›).MakeGenericType(typeof(string)) во время выполнения (что я и пробовал) - person mcintyre321; 26.11.2010
comment
Думаю, у меня есть это - я могу создать его во время выполнения, если захочу, но тогда у меня нет возможности добраться до .o без использования отражения моего типа, который медлителен. Вы должны сообщить компилятору об универсальном типе, если хотите получить доступ к .o. - person mcintyre321; 26.11.2010

Компилятор JIT знает адрес статической переменной o. Он разместил его в куче загрузчика. То, что он является членом универсального класса, не имеет значения. Другими словами, разрешение адреса статической переменной не требует поиска во время выполнения, это делается во время компиляции. Сгенерированный машинный код тривиален:

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

Обратите внимание на жестко закодированные адреса.

person Hans Passant    schedule 25.11.2010