Использование делегатов замедляет мои .NET-программы?

Использует ли делегаты замедление моих программ?

Я избегал их, потому что я действительно не понимаю, замедлит ли они мои программы. Я знаю, могу ли я вызвать исключение (catch), которое использует довольно много мощности процессора, но я не знаю о делегатах и ​​событиях и что .NET делает с ними.

Ответ 1

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

(Аналогично, при правильном использовании редко возникают проблемы с производительностью.)

Будет ли использование делегатов сделать ваш код более простым, понятным и более надежным? Если да, используйте их. Тщательно измерьте свою производительность и следите за ней. Отклонитесь от удобочитаемости ради производительности, только когда данные станут ясными.

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

Ответ 2

Просто небольшое дополнение к сообщению Jon: при использовании в обычном режиме С# (т.е. через lambdas/anonymous методы/обработчики событий /etc ), то они, безусловно, очень быстрые, но обратите внимание, что другое важное использование делегатов может быть выполнить динамический код (либо методы, созданные во время выполнения, либо существующие методы через отражение, и Delegate.CreateDelegate). При использовании этим вторым способом делегаты предлагают очень значительное улучшение скорости (по сравнению с отражением Invoke и т.д.).

Поэтому не стесняйтесь использовать делегатов. И, в частности, если у вас есть сомнения - измерьте его для реалистичного кода: бессмысленно, требуется ли 1 или 100 микро-ласок *, если это пока составляет только 0,01% от вашего общего времени выполнения.

* = просто какое-то сколь угодно малое время...

Ответ 3

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

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

Обычно это сводится к компромиссу между эффективностью и элегантностью кода. Допустим, вы создали самую удивительно элегантную, удобную и понятную базу кода в мире. Как только мы запускаем некоторые оптимизации производительности, мы начинаем облака кода с некоторыми, возможно, противостоящими интуитивно понятным, очень специализированным вещам. Если бы мы отправились в город по оптимизации, мы могли бы сделать экономию производительности, например, 5 или 10 процентов, но в процессе полностью уничтожить элегантность кода.

Вопрос: "Стоит ли это?".

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

Ответ 4

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

Я слышал, как люди бормотали о делегатах и ​​производительности CE, но насколько я обеспокоен его полным guff. Я слышал, что это "замедляет вызов метода на 30%", но если это 30% дрянного алгоритма, то чья это ошибка? Еще одно замедление в CE - это виртуальные методы, так как нет таблицы поиска, она вручную обрабатывает их в первый раз и кэширует результат. Это означает, что если вы промахните всю свою память, эти кеши будут очищены, и это приведет к тому, что в следующий раз будет достигнуто перфоманс. Но что считается, должны ли вы выбрасывать полезные навыки ООПа ради производительности?

Я нахожу, что многие из этих "OMG не используют слишком медленные" - это просто оправдания. В основном оправдания, потому что люди не знают, что действительно не так с их приложением, и его легко обвинить в внутренней работе CLR, а не в их собственном коде. Если ваша производительность отстойная, я бы посчитал, что 99,9% времени вы можете что-то изменить в своей части приложения или дизайна, которые не выбрасывают инструменты и не дают намного лучшего улучшения.