Что выполняет хуже: отражение или бокс? - PullRequest
8 голосов
/ 13 февраля 2010

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

Это подняло интересный вопрос относительно типов значений. Какой самый производительный:

a) Используя отражение, чтобы выбрать статический универсальный метод с правильным количеством параметров, затем используйте MakeGenericMethod для удаления универсальных

б) Перейти к старому объекту модных параметров [] и получить удар по боксу?

Ответы [ 5 ]

16 голосов
/ 13 февраля 2010

IME, время бокса ничто по сравнению с отражением.

3 голосов
/ 13 февраля 2010

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

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

3 голосов
/ 13 февраля 2010

Полагаю, что отражение будет намного медленнее, возможно, на несколько порядков.

Скамейка довольно проста, попробуйте и опубликуйте результаты:)

2 голосов
/ 10 июня 2013

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

Как уже говорили другие, здесь отражение медленнее (если только вы не кэшируете). Еще одна вещь, которая приходит в пользу бокса, это то, что вы, скорее всего, в любом случае будете боксировать, имея дело с отражением . API отражения всегда имеет дело с object, поэтому, если вы получаете какое-то значение экземпляра, вы должны распаковать его. Точно так же, вызов GetType для экземпляра типа значения сначала устанавливает его в object, что может потребоваться, если у вас нет аргумента типа, а только экземпляр.

Но лучшая альтернатива - полагаться на дженерики. Некоторые хорошие образцы подробно описаны здесь .

1 голос
/ 18 декабря 2012

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

С другой стороны, во многих сценариях будет возможно обработать миллион элементов некоторого универсального типа T, используя один раз Reflection для типа T, чтобы создать объект, который может обрабатывать что-то типа T без бокса, а затем кешировать результат этого на всю жизнь программы. Вот как работают такие вещи, как EqualityComparer<T>.Default. Такой подход легко может быть более чем на порядок быстрее, чем боксировать каждый предмет.

...