Насколько дорогой Исключения [дубликат]

20
задан Kai Huppmann 19 February 2009 в 22:41
поделиться

10 ответов

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

я получил следующие результаты:

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 {}
}

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

Моя спецификация:

  • Скомпилированный и работавший 1.5.0_16
  • WinXP SP3 Sun JVM
  • Intel Centrino Duo T7200 (2.00 ГГц, 977 МГц)
  • Ram

на 2,00 ГБ, По-моему, необходимо заметить, что методы неисключения не дают ошибку журнала в doSomethingElse, но вместо этого возвращают булевскую переменную так, чтобы код вызова мог иметь дело с отказом. Если существует несколько областей, в которые это может привести затем вход к сбою ошибки внутри, или выдача Исключения могла бы быть необходима.

6
ответ дан 29 November 2019 в 23:20
поделиться

Самая медленная часть выдачи исключения заполнение отслеживания стека .

, Если Вы предварительно создаете свое исключение и снова используете его, JIT может оптимизировать его вниз к" уровень goto машины. "

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

11
ответ дан 29 November 2019 в 23:20
поделиться

Исключения не являются бесплатными..., таким образом, они являются дорогими :-)

книга , Эффективный Java покрывает это в хороших деталях.

  • Объект 39 исключений Использования только для исключительных условий.
  • Объект 40 исключений Использования для восстанавливаемых условий

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

11
ответ дан 29 November 2019 в 23:20
поделиться

Медленная часть об исключениях создает отслеживание стека (в конструкторе 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

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

8
ответ дан 29 November 2019 в 23:20
поделиться

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

хорошо, это - ссылка относительно платформы.NET, но я думаю, что то же относится к Java также:

исключения & производительность

Тем не менее Вы не должны смущаться использовать их когда соответствующий . Это: не используйте их для управления потоком, но используйте их, когда что-то исключительное произошло; что-то, что Вы не ожидали происходить.

3
ответ дан 29 November 2019 в 23:20
поделиться

Это - по сути конкретная JVM, таким образом, Вы не должны вслепую полагать, что любой совет дан, но на самом деле имейте размеры в своей ситуации. Не должно быть трудно создать, "выдают миллион Исключений и распечатывают различие System.currentTimeMillis" для получения общего представления.

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

(Каждый раз, когда Вы делаете что-то замысловатым способом, что Вы заставляете работу unneccesary быть сделанной читателем для понимания, почему Вы сделали это как этот вместо просто обычного пути - что работа должна быть выровнена по ширине, по-моему, автором, тщательно объясняющим, почему это было сделано как этот как, ДОЛЖНА быть причина).

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

4
ответ дан 29 November 2019 в 23:20
поделиться

Я думаю, придерживаемся ли мы использования исключений, где они необходимы (исключительные условия), преимущества явно перевешивают любую потерю производительности, которую Вы могли бы платить. Я говорю, мог бы начиная со стоимости быть действительно функцией частоты, с которой исключения выдаются в запущенном приложении.
В примере Вы даете, похоже, что отказ не является неожиданным или катастрофическим, таким образом, метод должен действительно возвращать bool для передачи сигналов о его состоянии успеха вместо того, чтобы использовать исключения, таким образом делая их частью регулярного потока управления.
В нескольких работах улучшения производительности, в которые я был вовлечен, стоимость исключений была довольно низкой. Вы провели бы время намного большего количества времени в улучшении сложности общих, высоко повторяющихся операций.

3
ответ дан 29 November 2019 в 23:20
поделиться

Спасибо за все ответы.

я наконец следовал за предложением ThorbjГёrn и записал немного тестовой программы, измерив уровень сам. Результат: Никакой различие между этими двумя вариантами (в вопросах производительности).

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

оказалось, что вход ("Сообщение") (по сравнению со всем остальным случай) очень дорог, таким образом, я думаю, я избавлюсь от этого.

РЕДАКТИРОВАНИЕ :

тестовый код точно похож на тот в исходном сообщении, названном методом testPerfomance() в цикле, который окружается System.currentTimeMillis() - звонит для получения времени выполнения..., но:

я рассмотрел тестовый код теперь, превращенный всего остального (оператор журнала) и цикличное выполнение в 100 раз больше, чем прежде, и оказывается сохранением 4,7 секунд для миллиона вызовов при использовании B вместо из исходного сообщения. Как Ron сказал fillStackTrace, самая дорогая часть (+1 для того), и можно сохранить почти то же (4,5 секунды) при перезаписи его (в случае, Вам не нужен он, как я). В целом, это - все еще nearly-zero-difference в моем случае, так как код называют 1000 раз в час, и измерения показывают, что я могу сохранить 4.5 millis в то время...

Так, моя 1-я часть ответа выше немного вводила в заблуждение, но что я сказал о балансировке затрат-выгод рефакторинга, остается верным.

3
ответ дан 29 November 2019 в 23:20
поделиться

Скажем, исключение не произойдет при попытке выполнить операторы 1 и 2. Есть ли между теми двумя примерами кода КАКИЕ-ЛИБО хиты производительности?

, Если не, что, если DoSomething() метод должен сделать объем работы huuuge (загрузки вызовов к другим методам, и т.д.)?

1:

try
{
   DoSomething();
}
catch (...)
{
   ...
}

2:

DoSomething();
0
ответ дан 29 November 2019 в 23:20
поделиться

Я думаю, что Вы спрашиваете это от немного неправильного угла. Исключения разработаны для использования к исключительным случаям сигнала , и как механизм процесса выполнения программы для тех случаев. Таким образом, вопрос, который необходимо задавать, делает "логику" призыва кода к исключениям.

Исключения обычно разрабатываются для выполнения достаточно хорошо в использовании, для которого они предназначаются. Если они используются таким способом, которым они - узкое место, то, прежде всего, это - вероятно, признак, что они просто используются для "неправильной вещи" точка - т.е. что у Вас есть underlyingly, проблема дизайна программы , а не производительность проблема.

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

0
ответ дан 29 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: