Какие вещи я должен сделать, чтобы создать эффективный и надежный кэш отражения? - PullRequest
2 голосов
/ 11 октября 2008

В .NET 3.5 я собираюсь работать с System.Reflection, чтобы использовать AOP (вероятно, в контексте Виндзорских перехватчиков Касла) для таких вещей, как определение действий безопасности, которые необходимо выполнить на уровне метода и т. Д. Я слышал, что некоторые части Reflection работают медленно (я читал статью об этом в MSDN) и хотел бы кэшировать эти части (во всяком случае, когда я подойду ближе к рабочему коду). Я хотел бы подтвердить свой подход:

  • ключ кэша: {тип} + {имя метода с учетом регистра} + {список типов параметров}
  • объекты ключа кэша можно сравнивать с помощью операции Equals
  • полезная нагрузка кэша представляет собой {MethodInfo} + {список пользовательских атрибутов, определенных в методе}
  • кеш вводится в мои перехватчики с помощью конструктора
  • кэш может поддерживаться в течение длительного времени (исходя из предположения, что я не собираюсь писать самоизменяющийся код ;-))

Обновление:

Я не собираюсь вызывать методы через Reflection, то что я пишу сам; просто (на данный момент) ищите атрибуты тех, в которые я хочу добавить функциональность, где атрибуты определяют поведение для внедрения. Мои перехватчики в настоящий момент будут использовать механизм Виндзорского II-рецептора Касла, пока я не увижу причину для его изменения.

Ответы [ 2 ]

3 голосов
/ 11 октября 2008

Явный вызов MethodInfo действительно медленный - но вы можете сделать это намного, намного быстрее, если преобразуете его в делегат. См. этот блог , например. Конечно, это не помогает с точки зрения поиска методов и т. Д., Но если вы собираетесь вызывать метод повторно, стоит помнить.

Ключ кеша звучит достаточно просто для создания - типы и строки сравниваются красиво и легко. Значения всегда относительно просты:)

После создания кеш будет доступен только для чтения? Можете ли вы выделить фазы, чтобы гарантировать, что они не будут прочитаны до полной сборки? Если это так, вы сможете обойтись без какой-либо явной блокировки - в основном это словарь из вашего пользовательского типа ключа в ваш пользовательский тип значения.

1 голос
/ 11 октября 2008

Я бы согласился с большинством постов Джона - небольшим примечанием к словарю: с точки зрения производительности, вы можете захотеть сравнить это с простым списком. В прошлый раз, когда я делал эталонный тест (словарь против плоского списка, проверяя каждый элемент, пока не было найдено совпадение), точка разделения (для доступа на чтение) составляла около 150 элементов; ниже этого список был быстрее (просто через простоту). Но проведите свои собственные тесты ... (у меня нет цифр, чтобы доказать, так или иначе).

В зависимости от кода вы можете использовать обобщенные элементы для дальнейшего разделения данных - например, кэш-память, чтобы вся информация для типа T находилась в одном месте, заполняемая в статическом ctor для Cache. Это может или не может быть возможным, в зависимости от архитектуры.

Наконец, он может подходить или не подходить, но существуют существующие платформы AOP, такие как PostSharp, которые могут помочь упростить точки внедрения.

В общих словах - было бы довольно легко (в вашем коде инициализации) создать типизированный делегат для метода в методе Cache, чтобы уменьшить объем данных, через которые он должен сканировать - всего лишь часть Type. MakeGenericType и и Delegate.CreateDelegate - после этого момента код просто знает о вашем делегате Func <...> и ему не нужно заботиться о реализации.

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