Каков наиболее эффективный способ сопоставления информации с объектом «Тип» в .Net? - PullRequest
5 голосов
/ 30 апреля 2010

Я хочу связать пользовательские данные с типом и извлекать эти данные во время выполнения, невероятно быстро.

Это только мое воображение моего идеального мира:

var myInfo = typeof (MyClass) .GetMyInformation ();

это было бы очень быстро ... конечно, это не существует! Если бы это было так, я бы не спрашивал. хе-хе;)

Это способ использования пользовательских атрибутов:

var myInfo = typeof (MyClass) .GetCustomAttribute ("MyInformation");

это медленно, потому что требует поиска строки "MyInformation"

Это способ использования словаря :

var myInfo = myInformationDictionary [typeof (MyClass)];

Это также медленно, потому что это все еще поиск 'typeof (MyClass)'.

Я знаю, что словарь очень быстрый, но этого недостаточно ... он не такой быстрый, как вызов метода. Это даже не тот же порядок скорости.

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

Есть идеи ??

Спасибо!

EDIT:

typeof (MyClass), который я упоминал во всех предыдущих фрагментах, на самом деле является переменной ... Я не знаю, что это определенный тип MyClass, это может быть любой тип:

Тип myType = typeFromSomewhere;

т.е.. MyClass в данном случае просто говорит, что класс сделан мной, и любые другие типы, которые могут возникнуть в этой ситуации, также сделаны мной ... поэтому он читает

typeof ( Один из моих собственных классов, я не знаю, кто это, но он наверняка мой )

РЕДАКТИРОВАТЬ: ЗАКЛЮЧЕНИЕ

Некоторые результаты производительности, связанные со словарями:

Dic.buckets | Dic.Count | Dic.Key | Ops(x17)/s | Avg.Time | Min.Time | Max.Time
-----------------------------------------------------------------------------
     17519  |    12467  |   Type  |    1051538 |  0.95μs  |  0.86μs  |  0.42ms
       919  |      912  |   Type  |     814862 |  1.23μs  |  1.14μs  |  0.46ms
   1162687  |      912  |   Type  |    1126382 |  0.89μs  |  0.81μs  |  0.33ms
       919  |      912  |   Type  |     806992 |  1.24μs  |  1.16μs  |  0.21ms
        17  |       17  |   Type  |     872485 |  1.15μs  |  1.06μs  |  0.31ms
-----------------------------------------------------------------------------
     36353  |    18160  |  String |     227520 |  4.40μs  |  3.98μs  |  0.47ms
       919  |      911  |  String |     219159 |  4.57μs  |  4.14μs  |  0.29ms
   1162687  |      911  |  String |     236384 |  4.23μs  |  3.82μs  |  0.41ms
       919  |      911  |  String |     223042 |  4.49μs  |  4.10μs  |  0.43ms
        17  |       17  |  String |     229985 |  4.35μs  |  3.94μs  |  0.28ms

Интерфейс вызова:

ops(x17)/s: 2896001
Average: 0.35μs
Min: 0.34μs
Max: 1.20μs

Виртуальный звонок:

ops(x17)/s: 3115254
Average: 0.32μs
Min: 0.32μs
Max: 0.65μs

Я вижу, что у меня недооцененные словари !!! =) * * Тысяча семьдесят-две

Кажется, словарь типа для всего в 3–4 раза медленнее, чем вызов виртуального метода.

Это не тот случай, когда используется словарь строк. Это в 10-12 раз медленнее, чем вызов виртуального метода.

Итак, я доказал, что ошибаюсь!

И, нет, я не делаю ошибки !!! кто-то предположил это в комментарии ниже =)

Спасибо всем.

Ответы [ 8 ]

5 голосов
/ 30 апреля 2010

Dictionary<Type,Object> у меня работает.

5 голосов
/ 30 апреля 2010

Это не просто твой "идеальный мир", это тоже C #! Вы можете использовать методы расширения , чтобы сделать именно то, что вы предложили:

var myInfo = typeof(MyClass).GetMyInformation();

В статическом TypeUtilities классе или другом классе вы должны определить следующее:

public static InfoType GetMyInformation(this Type type)
{
    // Return InfoType object.
}

Относительно того, как вы на самом деле возвращаете информацию о типе, это можно сделать множеством способов. Простой if-блок, статический Dictionary, отражение в заданном типе (используя атрибуты / методы) или даже другие. Лучший подход во многом зависит от контекста и вашего конкретного сценария использования.

4 голосов
/ 30 апреля 2010

Если тип статически доступен, рассмотрите возможность использования чего-то вроде

public class Data<T, V>
{
    public static V Info;
}

который используется как,

Data<int, string>.Info = "A string associated with int";
Data<string, string>.Info = "A string associated with string";

и доступен как

Console.WriteLine(Data<int, string>.Info);
Console.WriteLine(Data<string, string>.Info);

Это работает, потому что статические переменные универсального класса уникальны для различных универсальных параметров.

Если тип статически недоступен, вам следует использовать Dictionary<Type, V>, как указано в вашем вопросе и рекомендовано другими.

2 голосов
/ 30 апреля 2010

Почему бы не использовать GetCustomAttributes(typeof(MyInformationAttribute), false)?

ИМХО, использование атрибутов - это семантически правильный способ выражения информации, подобной этой. Просто убедитесь, что вы используете закрытый класс атрибутов, так как это повышает производительность во время выполнения.

Хотя это не составит труда и, вероятно, предпочтительнее либо ленивой загрузки, либо каким-либо другим образом кэшировать экземпляры атрибута. Обычно я делаю это один раз, используя статическое поле при инициализации приложения.

2 голосов
/ 30 апреля 2010

Хм, как насчет использования словаря Dictionary<string, MyInformation>:

Вы знаете, что они пишут, что вы ищете, по определению, если вы используете метод typeof Вместо этого вы можете объявить const string MY_CLASS_TYPE_NAME = "MyNamespace.MyClass"

Это не самый красивый, но невероятно быстрый и не ограничивающий вашу функциональность.

2 голосов
/ 30 апреля 2010

Объявите статические свойства или методы для вашего типа.

class YourType
{
  public static string GetMyInformation()
  {
    return "Some info on this type";
  }
}

Затем вы можете получить доступ к данным в вашем коде следующим образом

var myInfo = YourType.GetMyInformation();

Или я упустил суть?

0 голосов
/ 01 мая 2010

Как уже говорили другие люди, вы, вероятно, микрооптимизируете, но так как мы все входим в дух этого, я тоже буду:)

Класс типов .NET можно свести к его дескриптору типа времени выполнения, который может быть более эффективным, чем полный тип, если вам не нужно отражение ...

Словарь или то, что вы используете, примерно на 20% быстрее, чем словарь в очень простом тесте, который я только что провел.

typeof(object).RuntimeTypeHandle;
// and
instance.GetType().RuntimeTypeHandle;

может использоваться вместо экземпляра полного типа

0 голосов
/ 30 апреля 2010

написать методы расширения для System.Type , которые будут выполнять все такие операции за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...