В Javascript стоит ли использовать блоки try-catch, даже если исключение никогда не выбрасывается?

"Медленно" использовать несколько блоков try-catch, если в них нет каких-либо исключений? Мой вопрос такой же, как этот, но для Javascript.

Предположим, что у меня есть 20 функций, в которых есть блоки try-catch. И еще одна функция, которая вызывает каждую из этих 20 функций. Ни один из них не выдаст исключение. Будет ли мой код работать медленнее или будет намного хуже из-за этих блоков try-catch?

Ответ 1

Вы делаете типичный код интерфейса CRUD? Используйте try catch, используйте петли, которые идут до 10000, без каких-либо причин, посыпанных вашим кодом, черт, используйте angular/ember - вы не заметите каких-либо проблем с производительностью.

Если вы используете библиотеку низкого уровня, физическое моделирование, игры, серверную часть и т.д., то никогда не бросая блок try-catch обычно не имеет значения, но проблема в том, что V8 не поддерживал его в своем оптимизирующем компиляторе до версии 6 движка, поэтому вся содержащая функция, которая синтаксически содержит улов try, не будет оптимизирована. Вы можете легко обойти это, создав вспомогательную функцию типа tryCatch:

function tryCatch(fun) {
    try {
        return fun();
    }
    catch(e) {
        tryCatch.errorObj.e = e;
        return tryCatch.errorObj;
    }
}
tryCatch.errorObj = {e: null};


var result = tryCatch(someFunctionThatCouldThrow);
if(result === tryCatch.errorObj) {
    //The function threw
    var e = result.e;
}
else {
    //result is the returned value
}

После версии V8 версии 6 (поставляется с Node 8.3 и последним Chrome) производительность кода внутри try-catch такая же, как и у обычного кода.

Ответ 2

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

Рассмотрим этот тест: http://jsperf.com/try-catch-performance-jls/2

Простой приращение выполняется при 356 800 000 итераций в секунду Тот же инкремент в try/catch составляет 93 500 000 итераций в секунду. Это накладные расходы 75% из-за попытки/улова. НО, тривиальный вызов функции выполняется с 112 200 000 итераций в секунду. 2 тривиальных вызова функций выполняются с 61 300 000 итераций в секунду.

Неиспользованная попытка в этом тесте занимает немного больше времени, чем один тривиальный вызов функции. Это вряд ли ограничение скорости, которое имеет значение, кроме самой внутренней петли чего-то действительно интенсивного, как БПФ.

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

Изменить: эти номера для Chrome на моей машине. В Firefox нет существенной разницы между неисследованной попыткой и отсутствием защиты вообще. По сути, нулевой штраф за использование try/catch, если исключение не выбрано.

Ответ 3

Блок try-catch считается дорогостоящим. Однако, если критическая производительность не является проблемой, использование ее не обязательно вызывает беспокойство.

Штраф ИМО:

  • читабельность
  • неуместно во многих случаях
  • неэффективно, когда дело доходит до асинхронного программирования.

Считываемость: использование вашего кода с большим количеством попыток является уродливым и отвлекающим

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

Async: блок try-catch является синхронным и не эффективен при программировании async. Во время запроса ajax вы обрабатываете события error и success в выделенных обратных вызовах. Нет необходимости в try-catch.

Надеюсь, что это поможет,

R.

Ответ 4

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

try {
  if (condition) {
    // ... do smth
  }
} catch ( err ) {
  // smth
}

со следующим вариантом:

if (condition) {
  try {
      // ... do smth
  } catch ( err ) {
    // smth
  }
}

в отрицательном состоянии?