Какова "стоимость" отображения .NET?

Возможный дубликат:
Насколько дорого стоит .NET-отражение?

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

Какова "реальная" стоимость использования отражения?

Стоит ли усиливать часто отображаемые типы, чтобы иметь кэшированное отражение, такое как наш собственный объектный код pre-LINQ DAL во всех свойствах для определения таблиц?

Будет ли объем кэширования памяти превышать использование процессора отражения?

Ответ 1

Отражение требует большого количества метаданных типа, которые должны быть загружены, а затем обработаны. Это может привести к увеличению объема памяти и более медленному выполнению. Согласно эта статья модификация свойства примерно на 2,5x-3x медленнее, а вызов метода на 3,5x-4x медленнее.

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

Существует также элемент сложности, который отражение может добавить к коду, что делает его существенно более запутанным и, следовательно, трудно работать. Некоторые люди, такие как Скотт Гензельман считают, что, используя рефлексию, вы часто делаете больше проблем, чем решаете. Это особенно важно, если ваши команды в основном младшие разработчики.

Вам может быть лучше изучить DLR (Dynamic Language Runtime), если вам нужно много динамического поведения. С новыми изменениями, внесенными в .NET 4.0, вы можете посмотреть, можете ли вы включить часть этого в свое решение. Добавленная поддержка динамических версий от VB и С# делает использование динамического кода очень элегантным и создает свои собственные динамические объекты довольно прямолинейно.

Удачи.

ИЗМЕНИТЬ: Я сделал еще несколько попыток прокрутить сайт Скотта и нашел это podcast при отражении. Я не слушал его, но это могло бы стоить.

Ответ 2

Есть много вещей, которые вы можете сделать, чтобы ускорить отражение. Например, если вы делаете много доступа к свойствам, то HyperDescriptor может оказаться полезным.

Если вы выполняете много методов, вы можете кэшировать методы для ввода делегатов с помощью Delegate.CreateDelegate - это тогда проверка типов и т.д. только один раз (во время CreateDelegate).

Если вы выполняете большую конструкцию объекта, то Delegate.CreateDelegate не поможет (вы не можете использовать его в конструкторе) - но (в 3.5) Expression можно использовать для этого, снова компилируя набранный делегат.

Итак, да: отражение медленное, но вы можете оптимизировать его без особых проблем.

Ответ 3

С великой силой приходит большая ответственность.

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

Одно из самых подходящих мест для использования - для IoC (Inversion of Control), поскольку, в зависимости от размера вашего приложения, вероятно, будет больше преимуществ, чем нет.

Ответ 4

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

Для нас это легче для наших младших разработчиков:

[TableName("Table")]
public class SomeDal : BaseDal
{
    [FieldName("Field")]
    public string Field
}

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

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

Ответ 5

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

Единственное решение - хорошая документация и тщательное тестирование модулей.