Влияет ли количество перехваченных исключений на производительность пробного кода? - PullRequest
7 голосов
/ 10 августа 2010

Я довольно часто читал, что использование try-catch довольно медленное по сравнению с обычным кодом.Теперь мне интересно, влияет ли количество обнаруженных исключений на производительность кода.

Так что

try{
  ...
}
catch(StrangeException e){
  ...
}

медленнее

try{
  ...
}
catch(StrangeException e){
  ...
}
catch(MysteriousException e){
  ...
}
catch(FrighteningException e){
  ...
}

?

Конечно, я имею в виду только код в предложении try, и если исключение не обнаружено.

Ответы [ 5 ]

5 голосов
/ 10 августа 2010

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

Я не думаю, что у меня когда-либо видел реальную ситуацию, когда исключения не генерируются, но наличие блоков try / catch было проблемой производительности.Как всегда, вы должны написать самый чистый код и проверить, как он работает.Подумайте только об изгибе идеального дизайна из соображений производительности, если у вас есть четкое свидетельство того, что изменения необходимы и полезны.

2 голосов
/ 10 августа 2010

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

Стоимость исключений возникает только , когда они действительно генерируются:

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

  • Бросать и ловить исключения - это немного дорого.В худшем случае JVM должна сделать эквивалент instanceof для каждого предложения catch каждого блока try / catch.Вот где большое количество предложений catch может повлиять на производительность.

0 голосов
/ 10 августа 2010

Я помню, что читал, что кто-то проверил это и обнаружил, что производительность в данном случае действительно пострадала, даже если вы, вероятно, не ожидаете этого.(Однако быстрый поиск в Google не показывает его, поэтому я не помню, сколько было блоков catch или в какой версии Java он был найден.)

0 голосов
/ 10 августа 2010

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

Когда происходит исключение, JVM знает, что нужно перейти к последовательности байт-кода, котораяреализует предложение catch путем поиска исключения в таблице, являющейся частью байт-кода класса.В общем, каждый метод, который перехватывает исключение, связан с таблицей исключений, которая является частью файла класса, вместе с байт-кодом метода.В таблице исключений есть запись для каждого перехваченного исключения каждым блоком try.Каждая запись содержит: начальную и конечную точки, смещение счетчика программы (ПК) в последовательности байт-кода, к которому необходимо перейти, и постоянный индекс пула типа исключения (т. Е. Класса), который перехватывается.

Еслиисключение выдается во время выполнения метода, JVM ищет в таблице исключений совпадение.Сопоставление происходит, если текущий ПК находится в пределах диапазона, указанного в записи, и если выброшенный класс исключений является тем, который указан в записи (или является его подклассом).

Итак, ответ на ваш вопросзависит от того, как этот поиск реализован.Насколько я знаю, JVM просматривает таблицу в том же порядке, в котором записи появляются в таблице, и когда первое совпадение найдено, JVM устанавливает ПК на новое место и продолжает выполнение оттуда.

Я думаю, что если бы у вас не было МНОГО исключений, вы бы не заметили значительного влияния, но если бы я был вами и если бы эта проблема была для меня критической, я бы сравнил это с конкретной JVM, которую вы используете.

Ori

0 голосов
/ 10 августа 2010

Единственный способ узнать наверняка с вопросами производительности - это тщательно протестировать его самостоятельно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...