Рефлексія: Чи використання рефлексії все ще є «поганим» чи «повільним»? Що змінилося з відображенням з 2002 року?


21

Я помічав, маючи справу з виразами або деревами виразів, я багато використовую для відображення, щоб встановити та отримати значення у властивостях і що у вас є. Мені прийшло в голову, що використання рефлексії стає все більш поширеним. Такі речі , як DataAnotations для перевірки, атрибутів важких ORMs і т.д. У мене цікаво: Що змінилося з часів року і років тому , коли я раніше сказав , щоб уникнути відображення , якщо це взагалі можливо?

То що, якщо щось змінилося? Це просто швидкість машин? Чи змінилися рамки для прискорення роздумів?

Або нічого насправді не змінилося? Чи все ж "погано" чи "повільно" використовувати рефлексію?


2
Відображення завжди буде повільніше, ніж прямі дзвінки, оскільки вам доведеться виконати кілька кроків, щоб знайти та перевірити, чи існує те, що ви телефонуєте.
Майкл К

Це було завжди погано .... Звичайно, іноді у вас немає вибору, це залежить від програміста, щоб знати, коли настають ті часи, і уникати цього інакше.
Рамхаунд

Виконання рефлексії за допомогою gettype, щоб витягнути один предмет у перерахунку, все ще перевищує 30 разів швидше, ніж кидати виняток за допомогою Enum.Parse (). Тож рефлексія перемагає іноді.
Brain2000

Відповіді:


16

Рефлексія не є ні поганою, ні повільною. Це просто інструмент. Як і всі інструменти, він дуже цінний для певних сценаріїв, не настільки цінний для інших.

Якщо продуктивність справді є проблемою, ви завжди можете використовувати бібліотеку на зразок FasterFlect .

Подальше читання
Якщо рефлексія неефективна, коли це найбільш доцільно?


Або dynamic- мабуть, на порядок швидше, ніж відображення.
Oded

1
Продуктивність - це зовсім не проблема. Я просто яскраво пам'ятаю, як люди уникали роздумів ще у 2002 році, як це була чума. Мені цікаво, що змінилося відтоді.
блеш

3
@blesh: Нічого. Зараз люди з ним більше знайомі і менше цього бояться.
Роберт Харві

5
Я міг би тут все "зійти з моєї газону" і сказати, що Лісп мав це ще задовго до існування ООП ...
Майкл К

Справедливо. Мені було просто цікаво, чи змінилися швидкості в машинах за останні десять років, чи зміни на System.Reflection були фактично внесені, які підвищили продуктивність.
м'ясо

17

Причина, з якою люди насторожено використовують рефлексію, - це не ефективність: так, є деяка накладні витрати на використання рефлексії, але часто для вирішення проблеми без неї потрібен інший підхід із порівнянною складністю, і навіть якщо цього не відбувається, накладні витрати є рідко значущий (особливо для розробки додаткового рівня).

Використовуючи роздуми, деякі важливі припущення, які зазвичай можна зробити про вихідний код, порушені, а такі інструменти, як "Знайти всі посилання", перестають надійно працювати. Рефлексія також в основному видаляє більшу частину безпеки типу, яку компілятор виконує, скажімо, на C #, і більшість помилок програмування, які типова система звичайно вловлює та перетворює на помилки компілятора, тепер стають помилками виконання в кращому випадку або дуже неясними помилками в гіршому випадку.

То чому тоді люди використовують рефлексію? Простіше кажучи, адже, незважаючи на описані вище проблеми, це дуже цінний інструмент. Зважаючи на відображення, деякі переваги динамічного програмування можна мати в статичній строго типізованій мові, як C #, а мови динамічного програмування показали свої заслуги останнім часом, особливо у царині веб-програмування - PHP, Javascript та досить помітно Python , всі використовують динамічний набір тексту та добре зарекомендували себе для веб-програмування. Але оскільки мова все ще є C #, ви можете зберегти більшу частину своєї програми у строго набраній ідіомі OOP та написати ту частину, де динамічна поведінка дійсно має значення з відображенням.

Типовий приклад - коли вам потрібно виставити методи як виклики веб-служб (використовуючи протокол, ще не вбудований у .NET). Суворо типовий підхід OOP дійсно працює, але він є надмірно обмежуючим і незграбним. Але якщо ви використовуєте відображення для відображення викликів методів та пар ключів / значень до аргументів, ви можете написати сантехніка для такої веб-служби один раз, а потім використовувати її в будь-якому класі, який вам подобається.


13

Відображення все ще значно повільніше, ніж прямі дзвінки. Дві речі змінилися:

  • Виконання оптимізували механізми відображення, щоб різниця стала меншою
  • Процесори стали швидше, щоб легкі терпіли невеликі неефективність

Ці два фактори разом призвели до зниження вартості роздумів до того, що ви можете регулярно використовувати його (де це доцільно від POV для ремонту) та чекати, коли профілер скаже вам, чи це насправді вузьке місце (і будьте впевнені, що більшість час його не буде).


4
На жаль, процесори стали повільнішими - як правило, на мобільних пристроях та сервері, де люди намагаються витіснити якомога більше ефективності зі своїх серверів через витрати на їх запуск.
gbjbaanb

@gbjbaanb: Я дам вам мобільні пристрої, але на сервері придбання більшої кількості апаратних засобів, а не оптимізація коду є прийнятним і раціональним вибором у переважній більшості випадків, оскільки витрати на придбання та запуск серверів настільки нижчі, ніж витрати на оптимізацію коду.
Майкл Боргвардт

2
У деяких ситуаціях витрати сервера різко перевищують витрати на розробку. У великому масштабному стилі. Навіть незважаючи на те, що сервери є незмінними, продуктивність може бути навіть критичнішою, ніж на клієнтській машині. Це в кожному конкретному випадку.
Лорд Тидус

1
@ Lord Tydus: звичайно, але випадок, який ви описуєте, є рідкісним винятком.
Майкл Боргвардт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.