Java try / catch производительность, рекомендуется ли сводить к минимуму то, что находится внутри предложения try? - PullRequest
33 голосов
/ 26 ноября 2010

Учитывая, что у вас есть такой код:

doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.

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

Мой вопрос таков: рекомендуется ли держать строки внутри перехвата попытки на минимальном уровне? Код внутри предложения try работает медленнее или вызывает снижение производительности?

Но более важно, что это лучший метод / более читаемое решение, учитывая следующее:

try {
    doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
}
catch (MyCheckedException e) {
   //handle it
}

или:

try {
    doSomething() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
   //Store my exception in a Map (this is all running in a loop and I want it to   continue running, but I also want to know which loops didn't complete and why)
   continue;     
} 
 //do some assignements calculations
try {
    doAnotherThing() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
    //Store my exception in a Map (this is all running in a loop and I want it to   continue running, but I also want to know which loops didn't complete and why)
   continue;
} 

Это с учетом того, что вы будете обрабатывать ВСЕ эти проверенные исключения совершенно одинаково, конечно.

Ответы [ 9 ]

23 голосов
/ 26 ноября 2010

Рекомендуется ли держать строки внутри улова минимума?

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

Работает ли код внутри предложения try медленнее или вызывает какие-либоснижение производительности?.

Нет.

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

Если вы беспокоитесь о производительности "try",безусловно, нужно сделать так, чтобы код был внутри максимум?

15 голосов
/ 26 ноября 2010

В приведенном здесь примере реальное снижение производительности заключается в том, что оба метода doSomething () и doAnotherThing () оба генерируют исключения.Ввод try-блока происходит быстро, пока он не выдаст исключение.

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

Редактировать: я прочитал в конце вашего комментария, вы предполагаете обрабатывать оба одинаково, и в этом случае я бы поместил их обоих в один и тот же блок try.

4 голосов
/ 26 ноября 2010

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

try {
    // op 1.
    // op 2.
    / ...
    // op n.
}
catch ( MyCheckedException error )
{
    // handle any `MyException` in op 1, 2 ... n.
}

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

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

3 голосов
/ 26 ноября 2010

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

Вы можете прочитать эту статью , чтобы получить представление о том, как JVM реализует обработку исключений в байт-коде: она создает «таблицы исключений», которые сопоставляютрегионы кода для блоков catch / finally, поэтому:

  • Байт-код для блока try такой же, как для стандартного блока {}
  • Единственная дополнительная плата вслучай «выбрасывания» - это «таблица исключений», загруженная в память.

Конечно, когда выбрасывается исключение, происходит много работы со стеком, поэтому она будет иметь стоимость,Во всяком случае, это не так плохо, как с SEH (исключения .NET).

2 голосов
/ 26 ноября 2010

Ваш код должен обрабатывать только те исключения, с которыми он может что-то делать, остальные должны быть переброшены.

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

1 голос
/ 26 ноября 2010

Сведение количества блоков try / catch к минимуму немного улучшит производительность, но перемещение работы не будет иметь большого значения, за исключением работы, которая будет пропущена из-за исключенного исключения.

0 голосов
/ 08 февраля 2011

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

Представьте себе операцию переноса баланса, которая не выполняется в 1% случаев из-за нехватки средств. Даже при таком относительно небольшом количестве отказов производительность может сильно пострадать.

См. Исходный код и результаты тестов здесь .

0 голосов
/ 26 ноября 2010

Я не уверен, что внутри блока try производительность может быть низкой, но я знаю, что производительность ex.getStackTrace() очень низкая, поскольку она раскрывает весь ваш стек команд, и вы должны быть осторожныс этим.

0 голосов
/ 26 ноября 2010

Для каждого блока исключения есть издержки.Итак, вы хотите максимизировать количество времени, которое вы оставаетесь в блоке.

Однако вы также должны учитывать разницу в семантике.В первом примере, если doSomething() выдает исключение, doAnotherThing() не будет запущено.Во втором примере (при условии, что обработчик перехвата не возвращается), будет запущено doAnotherThing().

...