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

Каким образом исключения С++ замедляют работу кода, если нет исключений?

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

Я не пытаюсь создать случай для или против исключений С++, основанных исключительно на том, что можно выполнить быстрее. Я слышал, что кто-то недавно сделал дело, что код с использованием исключений должен выполняться так же быстро, как и код на основе кодов возврата, как только вы учтете весь дополнительный код бухгалтерского учета, который потребуется для проверки возвращаемых значений и обработки ошибок. Что мне не хватает?

4b9b3361

Ответ 1

Существует стоимость, связанная с обработкой исключений на некоторых платформах и с некоторыми компиляторами.

А именно, Visual Studio при создании 32-битной цели будет регистрировать обработчик в каждой функции с локальными переменными с нетривиальным деструктором. В основном, он устанавливает обработчик try/finally.

Другой метод, используемый gcc и Visual Studio с таргетингом на 64-разрядные биты, несет только служебные данные при вызове исключения (метод включает в себя перемещение стека вызовов и поиска в таблице). В тех случаях, когда исключения редко выбрасываются, это может привести к более эффективному коду, поскольку коды ошибок не должны обрабатываться.

Ответ 2

Только попробуйте/поймайте и попробуйте/за исключением блока, выполните несколько инструкций по настройке. Накладные расходы обычно должны быть незначительными в каждом случае, за исключением самых сложных циклов. Но вы вообще не будете использовать try/catch/except во внутреннем цикле.

Я бы посоветовал не беспокоиться об этом и вместо этого использовать профилировщик, чтобы оптимизировать ваш код там, где это необходимо.

Ответ 3

Это полностью зависит от реализации, но многие недавние реализации имеют очень мало или вообще не имеют накладных расходов на производительность при исключении исключений. На самом деле вы правы. Правильно проверять коды возврата от всех функций в коде, который не использует исключения, может быть медленнее, чем делать ничего для кода с использованием исключений.

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

Ответ 4

Есть некоторые накладные расходы с исключениями (как указывали другие ответы).

Но сейчас у вас нет выбора. Попробуйте отключить исключения в своем проекте и убедитесь, что ВСЕ-зависимый код и библиотеки могут компилироваться и работать без него.

Работают ли они с отключенными исключениями?

Предположим, что они делают! Затем проверьте некоторые случаи, но обратите внимание, что вам нужно установить компилятор "отключить исключения". Без этого переключателя у вас все еще есть накладные расходы - даже если код никогда не генерирует исключения.

Ответ 5

Только накладные расходы - это ~ 6 инструкций, которые добавляют 2 SEH в начале функции и оставляют их в конце. Независимо от того, сколько попыток/уловов у вас есть в потоке, это всегда одно и то же.

И что это касается локальных переменных? Я слышу, как люди всегда жалуются на них при использовании try/catch. Я этого не понимаю, потому что в конце концов деконструкторы будут вызваны. Также вы не должны позволять исключению подниматься более чем на 1-3 вызова.

Ответ 6

Я взял тестовый код Chip Uni и немного расширил его. Я разделил код на два исходных файла (один с исключениями, один без). Я сделал каждый тест производительности 1000 раз, и я использовал clock_gettime() с CLOCK_REALTIME для записи времени начала и окончания каждой итерации. Затем я вычислил среднее значение и дисперсию данных. Я проверил этот тест с 64-разрядными версиями g++ 5.2.0 и clang++ 3.7.0 на ядре Intel Core i7 с 16-гигабайтной оперативной памятью, которая запускает ArchLinux с ядром 4.2.5-1-ARCH. Вы можете найти расширенный код и полные результаты здесь.

г ++

Без исключений
  • Среднее: 30 022 994 наносекунды
  • Стандартное отклонение: 1.25327e + 06 наносекунд
Исключения
  • Среднее: 30 025 642 наносекунды
  • Стандартное отклонение: 1,83422e + 06 наносекунд

лязг ++

Без исключений
  • В среднем: 20 954 657 наносекунд.
  • Стандартное отклонение: 426 662 наносекунды
Исключения
  • В среднем: 23 916 638 наносекунд.
  • Стандартное отклонение: 1.72583e + 06 наносекунд

Исключения только С++ допускают нетривиальное ограничение производительности с помощью clang++, и даже это наказание составляет только ~ 14%.