Подтвердить что ты не робот

Снижает ли производительность блока try-catch

Эта ссылка ,

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

Означает ли это, что наличие блока try снижает производительность из-за дополнительной задачи "проверки" во время выполнения?

4b9b3361

Ответ 1

TL; DR NO, исключения, как правило, выполняются быстрее на пути, отличном от ошибок, по сравнению с обработкой кода ошибки.


Ну, очевидное замечание сравнивается с чем?

По сравнению с отсутствием ошибки, это, очевидно, снижает производительность; но стоит ли производительность, которой не хватает правильности? Я бы сказал, что это не так, поэтому предположим, что вы имели в виду по сравнению с кодом ошибки, проверенным с помощью оператора if.

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

В С++, однако, все основные компиляторы (gcc представили его в серии 4.x, MSVC использует его для 64-битного кода) теперь используют модель исключения нулевой стоимости. Если вы прочитали этот технический документ, с которым связан Need4Sleep, он указан как ориентированный на таблицу подход. Идея состоит в том, что для каждой точки программы, которая может бросить вас, зарегистрируйте в боковом столе несколько бит и кусочков, которые позволят вам найти правильное предложение catch. Честно говоря, это более сложная реализация, чем предыдущие стратегии, однако имя Zero Cost определяется тем, что оно бесплатно, если не нужно исключать исключение. Сравните это с неверным предсказанием ветки на процессоре. С другой стороны, когда генерируется исключение, штраф огромен, потому что таблица хранится в холодной зоне (поэтому, вероятно, требуется обратная связь с ОЗУ или хуже)... но исключения являются исключительными, верно?

Подводя итог, при использовании современных компиляторов С++ исключения быстрее, чем коды ошибок, ценой больших двоичных файлов (из-за статических таблиц).

Ответ 2

Взгляните на раздел 5.4 проекта технический отчет о производительности на С++  в частности, о накладных расходах операторов try-catch в С++.

Небольшая выдержка из раздела:

5.4.1.1.2 Временные накладные расходы для подхода "Код"

• On entry to each try-block
    ♦ Commit changes to variables enclosing the try-block
    ♦ Stack the execution context 
    ♦ Stack the associated catch clauses 
• On exit from each try-block
    ♦ Remove the associated catch clauses 
    ♦ Remove the stacked execution context 
• When calling regular functions 
    ♦ If a function has an exception-specification, register it for checking 
• As local and temporary objects are created 
    ♦ Register each one with the current exception context as it is created 
• On throw or re-throw 
    ♦ Locate the corresponding catch clause (if any) – this involves some runtime check (possibly resembling RTTI checks) 
    If found, then: 
    destroy the registered local objects 
    check the exception-specifications of the functions called in-between 
    use the associated execution context of the catch clause 
    Otherwise: 
    call the terminate_handler6

Ответ 3

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

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

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

Ответ 4

Я бы порекомендовал добавить try catch в функции, которые выделяют память, удаляют, вызывают другие сложные функции и т.д. На самом деле производительность wise try catch добавляет немного накладных расходов.

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

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

Ответ 5

Это действительно зависит от конкретного компилятора.

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

Чтобы реализовать подход с нулевыми затратами, вы можете заметить, что в С++ вы не можете динамически изменять код, поэтому, как только вы знаете, что представляет собой стек стека, и адрес возврата, который он исправил, какие объекты должны быть уничтожены в случае разматывания или если есть раздел кода обработки исключений. Поэтому код для исключения исключений может проверить глобальную таблицу всех сайтов вызовов функций, чтобы решить, что делать.

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

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