Чому б не використовувати некерований безпечний код у C #


10

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

Однак мені цікаво, якщо ви впевнені, що ваш код не спричинить помилок, і ви знаєте, як обробляти пам'ять, то чому (якщо вам подобається швидкий код) дотримуйтесь загальних порад?

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

Зараз я взагалі дивуюсь, якщо ви впевнені, що у вас немає витоків пам'яті або ризику збоїв, чому б не використовувати частіше керований код?

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


8
unsafeозначає "знайте, що ви робите, і зважте переваги проти ризиків". Я використовував unsafeкілька разів, і це завжди було щось дуже специфічне, пов’язане з продуктивністю, яке можна було оградити за власним методом. Я не використовую його як загальну техніку програмування, оскільки більшість часу додаткова користь від продуктивності не вартує втрати безпеки.
Роберт Харві

14
Я написав багато кодів протягом багатьох років, які іноді виходили з ладу або мали витоки пам'яті, що я був впевнений, що не було витоків пам'яті або ризиків аварій.
whatsisname

1
Ось хороший unsafeприклад використання: stackoverflow.com/q/11660127/102937
Роберт Харві

3
Я думаю, що у вашому растровому коді все ще є помилки, але ви їх просто не виявили. І навіть якщо це не так, зачекайте, поки вам доведеться впровадити деякі нові вимоги в існуючий код.
Док Браун

1
Тому що навіть коли ви впевнені, що ваш код не спричинить помилок, він все-таки спричиняє помилки.
користувач253751

Відповіді:


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 зазвичай не можна використовувати небезпечний код, оскільки було б досить легко ввести вразливість через переповнення буфера. Іншим прикладом може бути кліконс. Або якщо до вашої програми зверталися з мережевої частки. Тож якщо ви плануєте використовувати свій код у різних сценаріях розгортання, небезпечний код виходить із гри.

В основному: його хмурять, оскільки це може ввести непотрібні помилки, можливо, це взагалі не матиме вигоди, і це зменшить можливість використання вашого коду.

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


4

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

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

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


* Просування за останні кілька десятиліть у технології оптимізації в компіляторах настільки скоротило цей проміжок, що це вже не є впевненою ставкою.


0

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

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


1
Я не думаю, що це має нічого спільного з правильністю чи простотою в обґрунтуванні ..
Jimmy Hoffa

Ніхто не говорить про формальне підтвердження коректності.

1
Я впевнений, що ваш пост пропускає суть, але я не формулюю офіційного доказу. Так само я можу бути впевнений, що моя програма правильна (наприклад, після широкого тестування, налагодження та тривалого використання в реальному світі, не виникаючи помилок), не підтверджуючи це раз і назавжди. Це тлумачення набагато ближче до того, що має на увазі більшість людей, коли вони говорять «впевнені, що це правильно». Формальні методи - це дуже ніша проблема, і зовсім не враховується для більшості розробників.

1
Я не бачу такого питання. Як я читав, питання полягає в тому, чому вхідний люк із керованого світу не / не слід використовувати частіше (мається на увазі, що дефолт до керованого коду має сенс). У будь-якому випадку, якщо ви хочете відповісти на це питання (вказавши на твердість забезпечення правильності), ви можете зробити це, не кажучи про абсолютну, формальну впевненість у правильності. Відтепер ваша відповідь обертається виключно повним, надійним доказом правильності для загальнообов'язкових мов. Але це надмірно, і я думаю, що докази щодо керованого C # однаково (або майже як) важкі.

1
@fish: Я бачу, що ти кажеш. Існує кореляція між тим, що важко довести, і тим, що важко міркувати. Якщо важко довести правильність, то, ймовірно, важко бути майже впевненим, що це правильно.
Майкл Шоу

0

Коротше кажучи, ніщо не заважає вам виконувати всі ці роботи та керувати бітами та болтами вашої програми в середовищі C ++. Оскільки ви впевнені, що ви можете правильно керувати усіма обручами пам’яті та протіканнями без смітника, тоді ви можете це зробити на C ++ :)

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

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

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


Ага, що цікаво, ви бачите, що я з мікроконтролера, і там, як правило, пишуть пристойний c ++, є мало місця для помилок і хороший хороший дизайн програмного забезпечення є ключовим, що потрібно зробити
user613326
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.