Который лучше/больше эффективен: проверьте на плохие значения или поймайте Исключения в Java

Это может ответить на Ваш вопрос

, Что действительно происходит в попытке {возвращают x;} наконец {x = пустой указатель;} оператор?

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

Тем не менее могло бы быть лучше реструктурировать Ваш код так или иначе именно так, это не смущает Вас позже или кого-то еще, кто может не знать об этом также.

14
задан Community 23 May 2017 в 10:27
поделиться

11 ответов

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

Точно так же ваш вопрос о том, как этот ответ может измениться в зависимости от языка / среды, связан с этим: Расходы исключений отличается в разных средах. .Net 1.1 и 2.0 невероятно медленнее, например, при первом вызове исключения.

9
ответ дан 1 December 2019 в 10:19
поделиться

Чисто с точки зрения эффективности и, учитывая ваши примеры кода, я думаю, это зависит от того, как часто вы ожидаете увидеть неверные значения. Если плохие значения не являются редкостью, сравнение выполняется быстрее, поскольку исключения стоят дорого. Однако, если неверные значения встречаются очень редко, возможно, будет быстрее использовать исключение.

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

6
ответ дан 1 December 2019 в 10:19
поделиться

Я неожиданно обнаружил небольшая текущая информация о стоимости выброса исключений. Совершенно очевидно, что они должны быть, вы создаете объект и, вероятно, получаете информацию о трассировке стека.

В конкретном примере, о котором вы говорите:

if (value1 == badvalue || value1 == badvalue2 || ...) {
      result = specificError;
 } else {
      DoSomeActionThatFailsIfValue1IsBad(value1);
      // ...
      result = success;
 }

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

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

3
ответ дан 1 December 2019 в 10:19
поделиться

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

2
ответ дан 1 December 2019 в 10:19
поделиться

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

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

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

например метод,

public int IsAuthenticated(String username, String password)
{

     if(!Validated(username,password)
     {
          // just an error
          // log it
          return -2;   
     }

     // contacting the Database here
     if cannot connect to db
     {
          // woww this is HUUGE
          throw new DBException('cannot connect'); // or something like that
     }

     // validate against db here
     if validated, return 0;

    // etc etc

}

это мои 2 цента

2
ответ дан 1 December 2019 в 10:19
поделиться

Мое личное мнение состоит в том, что исключения указывают на то, что что-то сломано - это вполне может быть API, вызванный с недопустимыми аргументами или делением на ноль, или файл не найден и т. Д. Это означает, что исключения могут быть вызваны проверка значений.

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

Это, на мой взгляд, хорошо. «Умный» код сложно осмыслить.

Кстати, JVM стали намного умнее - кодирование для повышения эффективности обычно не окупается.

1
ответ дан 1 December 2019 в 10:19
поделиться

Обычно можно было бы предположить, что try-catch дороже, потому что он выглядит тяжелее в коде, но это полностью зависит от JIT. Я предполагаю, что это невозможно сказать без реального случая и некоторых измерений производительности. Сравнение может быть более дорогим, особенно если у вас много значений, например, или потому что вам нужно вызвать equals () , поскольку == во многих случаях не сработает.

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

1
ответ дан 1 December 2019 в 10:19
поделиться

подобный вопрос подобен заданию,

"это более эффективно писать интерфейс или базовый класс со всеми абстрактными функциями »

имеет значение, что более эффективно? только один из них является правильным для данной ситуации

1
ответ дан 1 December 2019 в 10:19
поделиться

Обратите внимание: если ваш код не генерирует исключения, это не всегда означает, что ввод находится в установленных пределах. Использование исключений стандартной Java (API + JVM), таких как NullPointerException или ArrayIndexOutOfBoundsExceptions , является очень нездоровым способом проверки ввода. Входящий мусор иногда генерирует выход мусора, но без исключения .

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

0
ответ дан 1 December 2019 в 10:19
поделиться

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

Что еще более важно, исключения - это проблема стиля. Исключения для исключительных условий упрощают код, поскольку в нем меньше кода для проверки ошибок, поэтому фактическая функциональность более понятна и компактна.

Однако, если исключения могут возникать в более обычных обстоятельствах, существуют невидимые потоки управления, которые читатель должен имейте в виду, сравнимо с Intercal COME FROM ... ЕСЛИ ... заявление. (Интеркал был одним из самых ранних языков для шуток.) ​​Это очень сбивает с толку и может легко привести к неправильному прочтению и непониманию кода.

Мой совет, который применим ко всем языкам и средам, о которых я знаю:

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

Используйте блоки try бесплатно.

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

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

Используйте блоки try бесплатно.

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

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

Используйте блоки try бесплатно.

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

1
ответ дан 1 December 2019 в 10:19
поделиться

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

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

public void setAge(int age)
{
    if(age < 0)
    {
        throw new IllegalArgumentException("Array can't be negative");
    }

    this.age = age;
}

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

public void readFile(String filename) throws IOException
{
   File myfile = new File(filename);
   FileInputStream fis = new FileInputStream(myfile);

   //do stuff

   fis.read();

   //do more stuff
}

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

Надеюсь, что вы на правильном пути. Удачи!

Надеюсь, это направит вас на верный путь. Удачи!

Надеюсь, это направит вас на верный путь. Удачи!

0
ответ дан 1 December 2019 в 10:19
поделиться
Другие вопросы по тегам:

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