Давайте поговорим о том, что дорого об исключениях и обработке исключений.
Первое, на что нужно обратить внимание, это то, что попытка / отлов стоит почти ничего , если исключение не происходит.т происходит.Самое большее, может быть дополнительной инструкцией ветвления, чтобы перепрыгнуть через блок кода, который реализует обработчики, и я ожидаю, что JIT-компилятор обычно упорядочит блоки кода, чтобы избежать этого.
Бросать, распространять и обрабатывать исключения немного дороже, но не намного.У меня нет реальных чисел, но я подозреваю, что мы говорим только о десятках инструкций для каждого из них.
Действительно дорогостоящая часть обработки исключений в Java - это создание иинициализация объекта исключения до его выброса.И затраты происходят потому, что исключение должно захватывать и записывать информацию, которая позже будет выведена в трассировку стека.И стоимость пропорциональна глубине стека в точке, где создается объект исключения (и, как правило, также выбрасывается).
Суть в том, что общая стоимость создания, бросанияРаспространение исключения обычно составляет тысяч инструкций.Следовательно, Java-пословица о том, что исключения должны использоваться только для исключительных условий.
Так что же это означает на практике?
Давайте рассмотрим пример, аналогичный вашему:
public int toInt(String str, int dflt) {
try {
return Integer.parse(str);
} (NumberFormatException e) {
return dflt;
}
}
private static final Pattern numberPattern = Pattern.compile("-?\\d+");
public int toInt(String str, int dflt) {
if (numberPattern.matcher(str).matches()) {
return Integer.parse(str);
} else {
return dflt;
}
}
Две версии.Один допускает возникновение исключения и перехватывает его, а другой выполняет некоторую нетривиальную проверку, чтобы не создавать исключение в первую очередь.
Что является более эффективным?Ну, это зависит от вероятности того, что метод вызывается с неправильным номером.Например, если недопустимые номера встречаются один раз в 1000 вызовов, то во второй версии в 999 раз в 1000 раз применяется регулярное выражение без необходимости, чтобы избежать 1 случая, когда выбрасывается исключение;т.е. первая версия в среднем быстрее.С другой стороны, если недопустимые числа встречаются 1 раз в 2, то мы сравниваем стоимость двух вызовов для механизма регулярных выражений с одним созданным, брошенным и перехваченным исключением.И мои деньги на второй версии в среднем значительно быстрее.
В общем, решение, основанное исключительно на производительности, сводится к некоторой простой математике.Если p
- это вероятность возникновения исключения, A
- это средняя стоимость теста, чтобы избежать исключения, а E
- средняя стоимость создания / выброса / вылова, тогда вам нужно сравнить * 1037.* с (1 - p) * A
.Если первое меньше, то пусть произойдет исключение, а если второе меньше, избегайте исключения.
Конечно, получить точные значения или оценки для p
, A
и E
сложно,Таким образом, более практичный подход заключается в том, чтобы начать с интуиции, а затем профилировать свое приложение, чтобы увидеть необходимость оптимизации.