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

Логика работы веб-сервера такова, что если он не находит для заданного пути нужный обработчик, выбрасывается исключение, которое перехватывается вышестоящим обработчиком соединения, который, в свою очередь, отсылает клиенту ошибку 404. Время выполнения запроса1)Использовался горячий старт, когда перед контрольным замером проводилось несколько аналогичных запросов. представлено на нотариально заверенных скриншотах ниже.

webserver-correct-path

Время выполнения запроса: 1 миллисекунда. Надо так же учесть, что эта страница — не просто статический выдаваемый текст, а динамически генерируемый на основе Razor-шаблона. А теперь посмотрим, что будет, если мы запросим страницу для несуществующего обработчика, заставив код выбросить исключение.

webserver-not-found

Полное время выполнения запроса увеличилось до 8 миллисекунд (т.е. в 8 раз). Предыдущая страница выполняла обработку razor-шаблона, а эта — просто выдаёт статический текст! В этом случае ещё надо учесть, что выброс и обработка исключения в данном случае была оптимизирована мной и в других ситуациях задержка будет ещё больше. Это становится особенно заметно для серверных приложений, который могут обрабатывать тысячи запросов в секунду. Представьте, какая большая суммарная трата ресурсов на одни лишь исключения может образоваться в этом случае.

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

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

Если вы используете исключения по любому поводу — ударьте себя полбу.

comments powered by HyperComments

Заметки   [ + ]

1. Использовался горячий старт, когда перед контрольным замером проводилось несколько аналогичных запросов.