Налагодження та ефективність випуску


132

Я стикався з наступним пунктом:

"Налаштування відладки проти випуску в IDE при компіляції коду в Visual Studio майже не має ніякої різниці в продуктивності ... згенерований код майже однаковий. Компілятор C # насправді не робить оптимізації. Компілятор C # просто випльовує IL ... і під час виконання саме JITer робить всю оптимізацію. У JITer є режим налагодження / випуску, що робить величезну різницю в продуктивності. Але це не відключає, чи ви запускаєте конфігурацію налагодження чи випуску свого проекту, а відключає, чи додано налагоджувач. "

Джерело тут і подкаст тут .

Чи може хтось направити мене до статті Microsoft, яка насправді може це довести?

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


можливий дублікат відмінностей
версіями

З .Net4 на Win7-x86 у мене є обмежена програма на процесорі, про яку я писав, що працює у випуску майже в 2 рази швидше, ніж налагодження без тверджень / тощо в основному циклі.
Бенгі

Крім того, якщо ви дбаєте про використання пам’яті, можуть бути великі відмінності. Я бачив випадок, коли багатопотокова служба Windows, складена в режимі налагодження, використовувала 700 Мб на потік, проти 50 МБ на потік у версії версії. Збірка налагодження швидко втратила пам'ять у типових умовах використання.
о. нат

@Bengie - чи ви переконалися, що якщо ви приєднаєте налагоджувач до версії версії, вона все ще працює в 2 рази швидше? Зверніть увагу, що цитата вище говорить про те, що на оптимізацію JIT впливає те, чи додається налагоджувач.
ToolmakerSteve

Відповіді:


99

Частково правда. У режимі налагодження компілятор висилає символи налагодження для всіх змінних і компілює код таким, який є. У режимі випуску включені деякі оптимізації:

  • невикористані змінні взагалі не збираються
  • деякі змінні циклу компілятор виймає з циклу, якщо доведено, що вони є інваріантами
  • код, написаний відповідно до директиви #debug, не включається тощо.

Решта - до JIT.

Повний список оптимізацій сюди люб'язно Ерік Ліпперт .


10
І не забувайте про Debug.Asserts! У DEBUG-збірці, якщо вони не вдасться, вони зупиняють нитку та спливають вікно повідомлень. У випуску вони взагалі не складаються. Це стосується всіх методів, які мають [ConditionalAttribute].
Іван Златанов

13
Компілятор C # не робить оптимізацію хвостових викликів; тремтить. Якщо ви хочете отримати точний перелік того, що робить компілятор C #, коли перемикач оптимізації увімкнено, див. Blogs.msdn.com/ericlippert/archive/2009/06/11/…
Ерік Ліпперт

63

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

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

І крім того, ви зможете отримати значущі результати. "Повільніше" є безглуздим, оскільки не ясно, чи це на одну мікросекунд повільніше, або на двадцять хвилин повільніше. "На 10% повільніше в реалістичних умовах" є більш значущим.

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


2
Я думаю, що ви можете піклуватися про продуктивність, але все ще є бажання використовувати "налагодження". Наприклад, якщо більша частина вашого часу чекає на залежність, я не думаю, що побудова в режимі налагодження не призведе до великої різниці, але ви маєте додаткову перевагу в отриманні номерів рядків у слідах стека, що може допомогти швидше виправити помилки та зробити щасливіші користувачі. Справа в тому, що ви повинні зважити плюси і мінуси, і загальне твердження про "налагодження відбувається повільніше, але лише якщо ви пов'язані з процесором", достатньо, щоб допомогти у прийнятті рішення.
Джош Мауч

11

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


Я погоджуюся з вами з цього питання, але це не відповідає головному питанню
sagie

5
@sagie: так, я знаю про це, але я вважав, що питання все-таки варто зробити.
Конрад Рудольф

6

Від msdn соц

Це недостатньо задокументовано, ось що я знаю. Компілятор видає екземпляр System.Diagnostics.DebuggableAttribute. У версії налагодження властивість IsJitOptimizerEnabled є True, у версії випуску - False. Цей атрибут можна побачити в маніфесті збірки за допомогою ildasm.exe

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

Зіставлення точок зупинки на адреси виконання - це завдання налагоджувача. Він використовує файл .pdb та інформацію, згенеровану компілятором JIT, який надає інструкцію IL для відображення коду адрес. Якщо ви пишете власний налагоджувач, ви використовуєте ICorDebugCode :: GetILToNativeMapping ().

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


3

Те, що ви читаєте, цілком справедливо. Випуск, як правило, більш м'який через оптимізацію JIT, не враховуючи код налагодження (#IF DEBUG або [Conditional ("DEBUG")]), мінімальна завантаження символу налагодження і часто не враховується, це менша збірка, що скоротить час завантаження. Різниця продуктивності є більш очевидною при запуску коду в VS через більш обширний PDB та символи, які завантажуються, але якщо ви запускаєте його самостійно, відмінності в продуктивності можуть бути менш очевидними. Певний код буде оптимізований краще, ніж інші, і він використовує таку ж оптимізуючу евристику, як і в інших мовах.

Скотт має гарне пояснення з інлайн оптимізації методи тут

Дивіться цю статтю, яка дає коротке пояснення, чому вона відрізняється в середовищі ASP.NET для налаштування налагодження та випуску.


3

Варто зазначити одне, що стосується продуктивності та того, налагоджений прилад чи ні, те, що нас здивувало.

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

Винуватець виявився Debug.WriteLineв одній із щільних циклів, яка виплюнула тисячі журнальних повідомлень, залишених на сесії налагодження на деякий час назад. Здається, що коли налагоджувач приєднаний і прослуховує такий висновок, увімкнено накладні витрати, що уповільнює програму. Для цього конкретного коду він був порядком 0,2-0,3 секунди часу виконання самостійно та 30+ секунд, коли налагоджувач був приєднаний.

Хоча просте рішення, просто видаліть повідомлення про налагодження, які більше не потрібні.


2

На сайті msdn ...

Конфігурації випуску проти налагодження

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

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


1

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


1

Нещодавно я стикався з виступом. Повний список продуктів займав занадто багато часу, приблизно 80 секунд. Я налаштував БД, покращив запити, і різниці не було. Я вирішив створити TestProject і дізнався, що той самий процес був виконаний за 4 секунди. Потім я зрозумів, що проект знаходиться в режимі налагодження, а тестовий проект був у режимі випуску. Я перейшов основний проект у режим випуску, і для повного списку продуктів було потрібно лише 4 секунди, щоб відобразити всі результати.

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


Під "запущеним режимом" ви маєте на увазі "Випуск"?
Рон Кляйн

Так, саме. Випуск не має всі налагодження накладних витрат.
Франсіско Голденштейн

1

Режими налагодження та випуску мають відмінності. Існує інструмент Fuzzlyn : це фазер, який використовує Roslyn для генерації випадкових програм C #. Він запускає ці програми на ядро ​​.NET і забезпечує те, що вони дають однакові результати при компіляції в режимі налагодження та випуску.

За допомогою цього інструменту було знайдено і повідомили про багато помилок.

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