Почему бы не использовать неуправляемый безопасный код в C #

10

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

Однако мне интересно, если вы уверены, что ваш код не вызовет ошибок, и вы знаете, как обращаться с памятью, то почему (если вам нравится быстрый код) следуйте общим советам?

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

Теперь мне вообще интересно, если вы уверены, что у вас нет утечек памяти или рисков сбоев, почему бы не использовать неуправляемый код чаще?

PS мой опыт: я вроде как попал в этот мир программирования, и я работаю один (я делаю это в течение нескольких лет), и поэтому я надеюсь, что этот вопрос разработки программного обеспечения не так уж странен. У меня действительно нет других людей, таких как учитель, чтобы спрашивать такие вещи.

user613326
источник
8
unsafeозначает «знай, что ты делаешь, и сравнивай выгоды с рисками». Я использовал unsafeнесколько раз, и это всегда было что-то очень специфическое, связанное с производительностью, которое можно было огородить своим собственным методом. Я не использую его как общую технику программирования, поскольку в большинстве случаев дополнительное преимущество в производительности не стоит потери безопасности.
Роберт Харви
14
За эти годы я написал много кода, который иногда зависал или имел утечки памяти, и я был почти уверен, что у него нет утечек памяти или рисков сбоев.
whatsisname
1
Вот хороший unsafeпример использования: stackoverflow.com/q/11660127/102937
Роберт Харви
3
Полагаю, в вашем растровом коде все еще есть ошибки, но вы их просто не обнаружили. И даже если это не так, подождите, пока вам не придется внедрить некоторые новые требования в существующий код.
Док Браун
1
Потому что даже если вы уверены, что ваш код не вызовет ошибок, он все равно вызывает ошибки.
user253751

Ответы:

27

Ну, это в основном случай старой поговорки

  • Не оптимизировать
  • (только для экспертов) Пока не оптимизируйте

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

  1. Ошибки : Важная часть вашего вопроса - «если вы уверены, что ваш код не вызовет ошибок». Ну, как ты можешь быть абсолютно полностью уверен? Использовали ли вы средство проверки с формальным методом, гарантирующим правильный код? В программировании наверняка есть одна вещь: у вас будут ошибки. Когда вы снимаете безопасность, вы позволяете новым видам ошибок проникать через корыто. Когда вы позволяете сборщику мусора позаботиться о памяти для вас, многие проблемы исчезают.

  2. Не всегда так быстро, как вы думаете . Другой момент: в зависимости от проблемы, выигрыш может быть не таким большим. Хотя я не могу найти их прямо сейчас, я помню исследование, проведенное Google по сравнению скорости Java, Scala, Go и C ++. После оптимизации на местах, конечно, C ++ был намного быстрее. Но алгоритм, запрограммированный «идиоматическим» способом, был на самом деле не намного быстрее. Идиоматические в том смысле, что они использовали стандартную структуру и идиомы (контейнер stl, без развернутого цикла и т. Д.). Microsoft провела аналогичный эксперимент с C # и C ++. Раймонду Чену, одному из ведущих инженеров Microsoft, пришлось написать собственную реализацию std :: string, чтобы победить C #. (см .: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.htmlЗа гораздо меньшие усилия вы получаете довольно приличную производительность в управляемом коде, так что зачастую это не стоит проблем.

  3. Возможность повторного использования : небезопасный код можно использовать только в среде полного доверия. Например, на сервере ASP.NET вы обычно не можете использовать небезопасный код, так как было бы довольно легко представить уязвимость из-за переполнения буфера. Другим примером будет clickonce. Или если ваше приложение было доступно из общего сетевого ресурса. Поэтому, если вы планируете использовать свой код в различных сценариях развертывания, небезопасный код не входит в игру.

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

Но если ваш сценарий действительно требует его для производительности (и у вас есть данные, чтобы доказать это), вы - опытный программист, который знает, как обращаться с памятью, и ваш код будет использоваться в контролируемой среде, тогда обязательно сделайте это.

Лоран Бурго-Рой
источник
4

В некотором смысле, неуправляемый код является формой оплаты: вы покупаете более быстрое выполнение с дополнительными усилиями по разработке. Действительно, неуправляемый код требует больше времени для разработки, отладки и обслуживания. Правильно понять это - задача для большинства участников. В некотором смысле это похоже на программирование на ассемблере: конечно, вы можете выжать больше энергии из своего ЦП, если вы пишете на ассемблере * , но вы «тратите» гораздо больше усилий на этот путь.

Иногда разница во времени разработки очень значительна - дни, а не часы. Однако разница в скорости исполнения не столь значительна. Вот почему разработка неуправляемого кода зарезервирована для ситуаций, подобных той, что вы описали в своей публикации - локализованные, автономные реализации ресурсоемких алгоритмов, таких как обработка аудио и видео.

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


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

dasblinkenlight
источник
0

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

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

Тамас Селеи
источник
1
Я не думаю, что это имеет какое-либо отношение к правильности или простоте рассуждений ..
Джимми Хоффа
Никто не говорит о формальном доказательстве правильности.
1
Я уверен, что ваш пост не соответствует сути, но я не формулирую формальное доказательство. Кроме того, я могу быть уверен, что моя программа верна (например, после обширного тестирования, отладки и длительного использования в реальных условиях без каких-либо ошибок), не доказав это раз и навсегда. Эта интерпретация намного ближе к тому, что большинство людей имеют в виду, когда говорят «конечно, это правильно». Формальные методы - очень нишевая проблема, и для большинства разработчиков она совершенно не рассматривается.
1
Я не вижу такого вопроса. Насколько я понимаю, вопрос заключается в том, почему аварийный люк из управляемого мира не / не должен использоваться чаще (подразумевается, что использование управляемого кода по умолчанию имеет смысл). В любом случае, если вы хотите ответить на этот вопрос (указав на сложность обеспечения правильности), вы можете сделать это, не говоря об абсолютной, формальной уверенности в правильности. Ваш ответ на данный момент вращается исключительно вокруг полных, звуковых доказательств правильности для императивных языков. Но это излишне, и я думаю, что доказательства об управляемом C # одинаково (или почти так же) трудны.
1
@fish: Я вижу, что ты говоришь. Существует связь между чем-то, что трудно доказать, и чем-то, о чем трудно рассуждать. Если трудно доказать свою правоту, то очень вероятно трудно быть уверенным, что это правильно.
Майкл Шоу
0

Короче говоря, ничто не мешает вам выполнять всю эту работу и управлять фрагментами вашей программы в среде C ++. Поскольку вы абсолютно уверены, что вы можете правильно управлять всеми перебоями и утечками памяти без сборщика мусора, вы можете сделать это в C ++ :)

Напротив, C # имеет преимущества, обеспечивая безопасную / управляемую и строго типизированную среду разработки для безопасной работы в среде .NET.

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

Таким образом, возможность работать с неуправляемым кодом в .NET Framework начиная с 4.0 является опцией для крайних случаев, когда вы уверены, что это может принести вам выгоды, если вы не будете его использовать ...

Юсубы
источник
Ага, интересно, вы видите, что я из мира микроконтроллеров и там обычно пишут приличный с ++, там мало места для ошибок, и хороший хороший дизайн программного обеспечения - это ключевая вещь
user613326