Производительность выгоды попытки JavaScript по сравнению с кодом проверки ошибок

Это было бы быстрее, чтобы просто поместить код в блоке try-catch вместо того, чтобы выполнить различные проверки на ошибки?

Например..

function getProjectTask(projectTaskId) {
    if (YAHOO.lang.isUndefined(projectTaskId) || YAHOO.lang.isNull(projectTaskId) && !YAHOO.lang.isNumber(projectTaskId)) {
        return null;
    }

    var projectPhaseId, projectPhaseIndex, projectTaskIndex, projectPhases, projectPhase, projectTask;

    if (!YAHOO.lang.hasOwnProperty(projectTaskPhaseMap, projectTaskId)) {
        return null;
    }

    projectPhaseId = projectTaskPhaseMap[projectTaskId];

    if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhasesMap, projectPhaseId)) {
        return null;
    }

    projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId];
    if (YAHOO.lang.isUndefined(projectPhaseIndex) || YAHOO.lang.isNull(projectPhaseIndex) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhases[projectPhaseIndex])) {
        return null;
    }
    projectPhase = scheduleData.ProjectPhases[projectPhaseIndex];

    if (!YAHOO.lang.hasOwnProperty(projectPhase.ProjectTasksMap, projectTaskId)) {
        return null;
    }

    projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId];

    if (YAHOO.lang.isUndefined(projectTaskIndex) || YAHOO.lang.isNull(projectTaskIndex)) {
        return null;
    }

    projectTask = scheduleData.ProjectTasks[projectTaskIndex];
}

VS

function getProjectTask(projectTaskId) {
    try {
        projectPhaseId = projectTaskPhaseMap[projectTaskId];
        projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId];
        projectPhase = scheduleData.ProjectPhases[projectPhaseIndex];
        projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId];
        projectTask = scheduleData.ProjectTasks[projectTaskIndex];

    }
    catch (e) {
        return null;
    }
}

Я надеюсь, что мой вопрос имеет смысл. Я был бы рад разъясниться.Спасибо!

31
задан gblazex 12 July 2010 в 09:08
поделиться

4 ответа

«Программы должны быть написаны для людей читать, и только кстати для машины для выполнения ».

Abelson & Sussman, SICP, предисловие к первому изданию.

Всегда стремитесь к читаемому коду. Главное, что нужно помнить:

Избегайте пробных ошибок в производительности -критические функции и циклы

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

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

if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId))

можно записать как

if (projectPhaseId != null)

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

Готов поспорить , это работает , как и ожидалось:

function getProjectTask(projectTaskId) {

   var projectPhaseId    = projectTaskPhaseMap[projectTaskId],
       projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId],
       projectPhase      = scheduleData.ProjectPhases[projectPhaseIndex];

  if (projectPhase == null) return null; // projectPhase would break the chain

  var projectTaskIndex  = projectPhase.ProjectTasksMap[projectTaskId],
      projectTask       = scheduleData.ProjectTasks[projectTaskIndex];

   return projectTask || null; // end of the dependency chain

}

Как ] круто это? :)

47
ответ дан 27 November 2019 в 21:43
поделиться

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

3
ответ дан 27 November 2019 в 21:43
поделиться

Зависит от ситуации. Как упоминает galambalazs, читабельность важна. Рассмотрим:

function getCustomer (id) {
  if (typeof data!='undefined' && data.stores && data.stores.customers 
      && typeof data.stores.customers.getById=='function') {
    return data.stores.customers.getById(id);
  } else {
    return null;
  }
}

по сравнению с:

function getCustomer (id) {
  try {return data.stores.customers.getById(id);} catch (e) { return null; }
}

Я бы сказал, что второй вариант гораздо более читабелен. Вы обычно получаете такие данные из таких вещей, как google's apis или twitter's feeds (обычно не с глубоко вложенными методами, но это просто для демонстрации).

Конечно, производительность также важна, но в наши дни движки javascript достаточно быстры, чтобы никто не заметил разницы, если только вы не собираетесь вызывать getCustomer каждые десять миллисекунд или что-то в этом роде.

1
ответ дан 27 November 2019 в 21:43
поделиться

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

Вот интересный слайд-шоу, в котором рассматриваются некоторые соображения относительно производительности JavaScript. На слайде 76 они охватывают блоки try / catch и влияние на производительность. http://www.slideshare.net/madrobby/extreme-javascript-performance

0
ответ дан 27 November 2019 в 21:43
поделиться
Другие вопросы по тегам:

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