Я читал довольно часто, та выгода попытки использования является довольно медленной по сравнению с нормальным кодом. Теперь интересно, влияет ли количество перехваченных исключительных ситуаций на производительность кода или нет.
Так
try{
...
}
catch(StrangeException e){
...
}
медленнее, чем
try{
...
}
catch(StrangeException e){
...
}
catch(MysteriousException e){
...
}
catch(FrighteningException e){
...
}
?
Конечно, я только обращаюсь к коду в пункте попытки и если никакое исключение не поймано.
Стоимость блока try / catch практически равна нулю, если на самом деле не генерируются исключения. Количество предложений о перехвате не имеет значения.
Стоимость исключений возникает только , когда они фактически генерируются:
Создание объекта исключения очень дорого из-за стоимости шага fillInStackTrace ()
. Это должно создать и инициализировать структуру данных, содержащую ключевые детали всех фреймов в текущем стеке потока. В худшем случае их могут быть тысячи.
Создание и перехват исключений - это немного дорого. В худшем случае JVM необходимо выполнить эквивалент instanceof
для каждого предложения catch
каждого блока try / catch. Именно здесь наличие большого количества предложений catch
может повлиять на производительность.
То, что вы прочитали, неверно. Значительные накладные расходы возникают, когда действительно генерируется исключение - обычно накладные расходы минимальны, когда нет исключений. Единственным исключением является то, что это может повлиять на встраивание - поэтому, если у вас есть метод, который вызывается в жестком цикле, вы можете обнаружить, что он не встраивается, если у него есть блоки try / catch. Точно так же только наличие кода может повлиять на согласованность кэша и другие тонкости ... но в большинстве ситуаций этот не будет узким местом.
Не думаю, что я когда-либо видел реальную ситуацию, когда исключения не генерируются, но наличие блоков try / catch было проблемой с производительностью. Как всегда, вы должны написать максимально чистый код и проверить, как он работает. Рассматривайте изменение формы идеальной конструкции по соображениям производительности только тогда, когда у вас есть четкие доказательства того, что изменения необходимы и полезны.
Единственный способ узнать наверняка в вопросах производительности - это тщательно протестировать ее самостоятельно.
Но если бы вы попросили меня поспорить, я бы поспорил, что это вообще не имеет ощутимой разницы, и что даже использование try/catch по сравнению с его неиспользованием не имеет большой разницы, до тех пор, пока исключения действительно не будут брошены (чего не должно быть, в обычном случае).
Насколько я помню из своих старых дней чтения байткода, количество catch-клаузул не оказывает существенного влияния на производительность.
Когда возникает исключение, JVM знает, что нужно перейти к последовательности байткода, которая реализует предложение catch, путем поиска исключения в таблице, которая является частью байткода класса. В общем, каждый метод, который ловит исключение, связан с таблицей исключений, которая является частью файла класса вместе с байткодом метода. В таблице исключений есть запись для каждого исключения, пойманного каждым try-блоком. Каждая запись содержит: начальную и конечную точки, смещение программного счетчика (PC) в последовательности байткода для перехода, и индекс константного пула типа (т.е. класса) перехватываемого исключения.
Если во время выполнения метода возникает исключение, JVM ищет совпадение в таблице исключений. Совпадение происходит, если текущий ПК находится в диапазоне, указанном в записи, и если класс выброшенного исключения соответствует классу, указанному в записи (или является его подклассом).
Таким образом, ответ на ваш вопрос зависит от того, как реализован этот поиск. Насколько я знаю, JVM ищет по таблице в том же порядке, в котором записи появляются в таблице, и когда найдено первое совпадение, JVM устанавливает PC в новое место и продолжает выполнение оттуда.
Я думаю, что если у вас нет большого количества исключений, вы не заметите значительного влияния, но если бы я был на вашем месте и если бы этот вопрос был для меня критичным, я бы проверил это на конкретной JVM, которую вы используете.
Ori
Я действительно помню, как читал, что кто-то тестировал это и обнаружил, что производительность в данном случае действительно пострадала, хотя вы, вероятно, этого не ожидали. (Быстрый поиск в Google не показывает его, поэтому я не помню, сколько было блоков catch и в какой версии Java он был обнаружен.)