Я не потрудился читать на Исключениях, но выполнении очень быстрого теста с некоторым измененным вашим кодом, я прихожу к выводу что обстоятельство Исключения довольно много медленнее, чем булев случай.
я получил следующие результаты:
Exception:20891ms
Boolean:62ms
Из этого кода:
public class Test {
public static void main(String args[]) {
Test t = new Test();
t.testException();
t.testBoolean();
}
public void testException() {
long start = System.currentTimeMillis();
for(long i = 0; i <= 10000000L; ++i)
doSomethingException();
System.out.println("Exception:" + (System.currentTimeMillis()-start) + "ms");
}
public void testBoolean() {
long start = System.currentTimeMillis();
for(long i = 0; i <= 10000000L; ++i)
doSomething();
System.out.println("Boolean:" + (System.currentTimeMillis()-start) + "ms");
}
private void doSomethingException() {
try {
doSomethingElseException();
} catch(DidNotWorkException e) {
//Msg
}
}
private void doSomethingElseException() throws DidNotWorkException {
if(!isSoAndSo()) {
throw new DidNotWorkException();
}
}
private void doSomething() {
if(!doSomethingElse())
;//Msg
}
private boolean doSomethingElse() {
if(!isSoAndSo())
return false;
return true;
}
private boolean isSoAndSo() { return false; }
public class DidNotWorkException extends Exception {}
}
я по-дурацки не прочитал свой код достаточно хорошо и ранее имел ошибку в нем (как смущение), если бы кто-то мог бы утроить проверку этот код, я был бы очень признателен за его, на всякий случай я впадаю в маразм.
Моя спецификация:
на 2,00 ГБ, По-моему, необходимо заметить, что методы неисключения не дают ошибку журнала в doSomethingElse, но вместо этого возвращают булевскую переменную так, чтобы код вызова мог иметь дело с отказом. Если существует несколько областей, в которые это может привести затем вход к сбою ошибки внутри, или выдача Исключения могла бы быть необходима.
Самая медленная часть выдачи исключения заполнение отслеживания стека .
, Если Вы предварительно создаете свое исключение и снова используете его, JIT может оптимизировать его вниз к" уровень goto машины. "
Все, что, будучи сказанным, если код от Вашего вопроса не находится в действительно жестком цикле, различие будет незначительно.
Исключения не являются бесплатными..., таким образом, они являются дорогими :-)
книга , Эффективный Java покрывает это в хороших деталях.
автор нашел, что исключения привели к коду, настраивающемуся в 70 раз медленнее для его тестового сценария на его машине с его конкретным VM и комбинацией ОС.
Медленная часть об исключениях создает отслеживание стека (в конструкторе java.lang.Throwable
лет), который зависит от глубины стека. Бросок сам по себе не является медленным.
исключения Использования к пропаданиям сигнала. Влияние производительности затем незначительно, и отслеживание стека помогает точно определить причину отказа.
при необходимости в исключениях для потока управления (не рекомендуемый), и профильные шоу, что исключениями является узкое место, затем создайте подкласс Исключения, который переопределяет fillInStackTrace()
с пустой реализацией. Кроме того (или дополнительно) инстанцируют только одного исключения, хранят его в поле и всегда бросают тот же экземпляр.
следующее демонстрирует исключения без отслеживаний стека путем добавления одного простого метода для микро сравнительного теста (, хотя испорчено ) в принятый ответ :
public class DidNotWorkException extends Exception {
public Throwable fillInStackTrace() {
return this;
}
}
Выполнение его с помощью JVM в -server
режим (версия 1.6.0_24 в Windows 7) приводит к:
Exception:99ms
Boolean:12ms
Exception:92ms
Boolean:11ms
разница является достаточно небольшой, чтобы быть игнорируемой на практике.
У меня нет реальных измерений, но выдача исключения является более дорогой.
хорошо, это - ссылка относительно платформы.NET, но я думаю, что то же относится к Java также:
исключения & производительность
Тем не менее Вы не должны смущаться использовать их когда соответствующий . Это: не используйте их для управления потоком, но используйте их, когда что-то исключительное произошло; что-то, что Вы не ожидали происходить.
Это - по сути конкретная JVM, таким образом, Вы не должны вслепую полагать, что любой совет дан, но на самом деле имейте размеры в своей ситуации. Не должно быть трудно создать, "выдают миллион Исключений и распечатывают различие System.currentTimeMillis" для получения общего представления.
Для фрагмента кода Вы перечисляете, я лично потребовал бы исходного автора к полностью документу, почему он использовал исключение, бросающее здесь, поскольку это не "путь наименьшего количества неожиданностей", который крайне важен для поддержания его позже.
(Каждый раз, когда Вы делаете что-то замысловатым способом, что Вы заставляете работу unneccesary быть сделанной читателем для понимания, почему Вы сделали это как этот вместо просто обычного пути - что работа должна быть выровнена по ширине, по-моему, автором, тщательно объясняющим, почему это было сделано как этот как, ДОЛЖНА быть причина).
Исключения очень, очень полезный инструмент, но должны только использоваться при необходимости :)
Я думаю, придерживаемся ли мы использования исключений, где они необходимы (исключительные условия), преимущества явно перевешивают любую потерю производительности, которую Вы могли бы платить. Я говорю, мог бы начиная со стоимости быть действительно функцией частоты, с которой исключения выдаются в запущенном приложении.
В примере Вы даете, похоже, что отказ не является неожиданным или катастрофическим, таким образом, метод должен действительно возвращать bool для передачи сигналов о его состоянии успеха вместо того, чтобы использовать исключения, таким образом делая их частью регулярного потока управления.
В нескольких работах улучшения производительности, в которые я был вовлечен, стоимость исключений была довольно низкой. Вы провели бы время намного большего количества времени в улучшении сложности общих, высоко повторяющихся операций.
Спасибо за все ответы.
я наконец следовал за предложением ThorbjГёrn и записал немного тестовой программы, измерив уровень сам. Результат: Никакой различие между этими двумя вариантами (в вопросах производительности).
Даже при том, что я не спрашивал об эстетике кода или чем-то, т.е. что намерение исключений было и т.д. большинством из Вас, обратился также к той теме. Но в действительности вещи не всегда настолько ясны... В случае на рассмотрении код родился давным-давно, когда ситуация, в которой выдается исключение, казалось, была исключительной. Сегодня библиотекой пользуются по-другому, поведение и использование различных измененных приложений, тестовое покрытие не очень хорошо, но код все еще делает это - задание, просто немного слишком медленное (Вот почему, я попросил производительность!!). В той ситуации, я думаю, должно быть серьезное основание для изменения от до B, который, по-моему, не может быть, "Это не то, для чего были сделаны исключения!".
оказалось, что вход ("Сообщение") (по сравнению со всем остальным случай) очень дорог, таким образом, я думаю, я избавлюсь от этого.
РЕДАКТИРОВАНИЕ :
тестовый код точно похож на тот в исходном сообщении, названном методом testPerfomance()
в цикле, который окружается System.currentTimeMillis()
- звонит для получения времени выполнения..., но:
я рассмотрел тестовый код теперь, превращенный всего остального (оператор журнала) и цикличное выполнение в 100 раз больше, чем прежде, и оказывается сохранением 4,7 секунд для миллиона вызовов при использовании B вместо из исходного сообщения. Как Ron сказал fillStackTrace
, самая дорогая часть (+1 для того), и можно сохранить почти то же (4,5 секунды) при перезаписи его (в случае, Вам не нужен он, как я). В целом, это - все еще nearly-zero-difference в моем случае, так как код называют 1000 раз в час, и измерения показывают, что я могу сохранить 4.5 millis в то время...
Так, моя 1-я часть ответа выше немного вводила в заблуждение, но что я сказал о балансировке затрат-выгод рефакторинга, остается верным.
Скажем, исключение не произойдет при попытке выполнить операторы 1 и 2. Есть ли между теми двумя примерами кода КАКИЕ-ЛИБО хиты производительности?
, Если не, что, если DoSomething()
метод должен сделать объем работы huuuge (загрузки вызовов к другим методам, и т.д.)?
1:
try
{
DoSomething();
}
catch (...)
{
...
}
2:
DoSomething();
Я думаю, что Вы спрашиваете это от немного неправильного угла. Исключения разработаны для использования к исключительным случаям сигнала , и как механизм процесса выполнения программы для тех случаев. Таким образом, вопрос, который необходимо задавать, делает "логику" призыва кода к исключениям.
Исключения обычно разрабатываются для выполнения достаточно хорошо в использовании, для которого они предназначаются. Если они используются таким способом, которым они - узкое место, то, прежде всего, это - вероятно, признак, что они просто используются для "неправильной вещи" точка - т.е. что у Вас есть underlyingly, проблема дизайна программы , а не производительность проблема.
С другой стороны, если исключение, кажется, "используется для правильной вещи", затем это, вероятно, означает, что будет также работать хорошо.