У статті Мета Воррена, він ефективно пояснює, чому винятки (exceptions) повинні бути справді винятковими. Ключовий момент полягає в тому, що використання винятків має бути рідкісним і специфічним, щоб уникати їх появи в нормальному потоці програми. Наприклад, багато керівних принципів кодування NASA забороняють використання винятків. Точно так само, керівні принципи Microsoft не рекомендують використовувати винятки в звичайній логіці програми.
Розглянемо приклад тестування, що порівнює методи, які використовують винятки, з тими, які їх не використовують. Метод “result” обробляє помилки без винятків, в той час як метод “exception” покладається на викидання винятків. Зверніть увагу на значну різницю у швидкості виконання.
Завжди намагайтеся використовувати шаблон результату (Result Pattern) для ефективної обробки помилок. Посилання на туторіал
До цього часу ми виділили переваги мінімізації використання винятків. Але що ж із .NET?
Все почалося з проблеми, що була виявлена у 2019 році в проекті .NET runtime. Це запит, створений Chrishaly, піднімав питання: чому створення винятку в .NET займає приблизно в 10 разів більше часу, ніж в Java? Запит містив сценарій порівняння створення винятків у .NET і Java, що чітко показувало значну повільність .NET. Ця проблема незабаром привернула увагу і була обговорена в подальшому звіті.
Посилання на Issues 1 — Посилання на Issues 2
Давайте розглянемо код Microsoft. Якщо ви переглянете кодову базу .NET, ви помітите, що винятки часто використовуються для обробки помилок, що призводить до значних уповільнень і збоїв. Процес створення винятку в принципі є повільним.
Наприклад, я розробив середнього розміру проект, де не створювалися вручну винятки, а помилки оброблялися за допомогою шаблону результату (Result Pattern). Однак давайте подивимося на метрики. Попри те, що ми уникали створення винятків вручну, все одно відбулося понад 1000 винятків під час виконання. Дивіться нижче для деталей.
Microsoft доклала зусиль, щоб рефакторизувати частини своєї кодової бази, щоб зменшити залежність від викидання винятків. Наприклад, у класі HttpConnectionPool
, викидання винятків спричинило значне уповільнення в .NET 7, що призвело до змін, спрямованих на покращення продуктивності. Посилання
Однак найбільший прогрес у цій галузі був досягнутий із .NET 9, де редизайн компонентів Runtime та CoreCLR в Microsoft призвів до значних покращень. Були реалізовані численні оптимізації, що дозволили вирішити багато неефективностей, спричинених надмірною обробкою винятків.
Посилання 1 — Посилання 2 — Посилання 3
Результати цих змін були вражаючими, досягнувши покращень приблизно на 50% до 76% у різних сценаріях.
Ці відносно прості зміни можуть значно покращити продуктивність при оновленнях вашого .NET.
Якщо це було цікаво, не соромтеся поділитися цим!
Перекладено з: Why Exceptions Should Be Exceptional?