Ответ 1
Я поддержал ответ Matt Joiner, но хотел включить некоторые дополнительные замечания, чтобы дать понять, что наряду с несколькими другими факторами существует 4, что имеет значение при выборе между условиями предварительной проверки (известный как LBYL или "Look Before You Leap" ) и просто обработка исключений (известная как EAFP или "проще просить прощения, чем разрешения" ).
Эти тайминги:
- Сроки, когда проверка завершается с помощью LBYL
- Сроки, когда проверка не выполняется с помощью LBYL
- Сроки, когда исключение не выбрасывается с помощью EAFP
- Сроки, когда исключение генерируется с помощью EAFP
Дополнительные факторы:
- Типичное отношение успеха/неудачи проверки или исключение брошенных/не бросаемых случаев
- Есть ли условие гонки, которое предотвращает использование LBYL
Последняя точка - это та, которая должна быть решена первой: если есть вероятность для состояния гонки, тогда у вас нет выбора, вы должны использовать обработку исключений. Классический пример:
if <dir does not exist>:
<create dir> # May still fail if another process creates the target dir
Так как LBYL не исключает исключения, это такие случаи, он не дает никакой реальной выгоды, и нет никакого решения о вызове: EAFP - это единственный подход, который будет корректно обрабатывать состояние гонки.
Но если нет условия гонки, любой подход потенциально жизнеспособен. Они предлагают различные компромиссы:
- Если исключение не создано, тогда EAFP находится рядом со свободным
- однако, это сравнительно дорого, если возникает исключение, так как при разматывании стека довольно много обработки, создавая исключение и сравнивая его с предложениями об обработке исключений
- LBYL, напротив, несет потенциально высокую фиксированную стоимость: дополнительная проверка всегда выполняется независимо от успеха или неудачи.
Это приводит к следующим критериям принятия решения:
- Известно ли, что эта часть кода имеет решающее значение для скорости приложения? Если нет, то не беспокойтесь о том, какая из двух быстрее, беспокоиться о том, какая из двух легче читать.
- Является ли предварительная проверка более дорогой, чем стоимость поднятия и исключения? Если да, то EAFP всегда быстрее и должен использоваться.
- Все становится интереснее, если ответ "нет". В этом случае, что быстрее, будет зависеть от того, является ли успех или случай ошибки более распространенным, и относительная скорость предварительной проверки и обработки исключений. Ответ на это окончательно требует реальных измерений времени.
В качестве грубого эмпирического правила:
- если существует потенциальное состояние гонки, используйте EAFP
- Если скорость не является критичной, используйте только то, что вам кажется более удобным для чтения.
- Если предварительная проверка стоит дорого, используйте EAFP
- если вы ожидаете, что операция будет успешной большую часть времени *, используйте EAFP
- если вы ожидаете, что операция завершится с ошибкой более половины времени, используйте LBYL
- если есть сомнения, измерьте его
* Люди будут отличаться от того, что они считают "большую часть времени" в этом контексте. Для меня, если я ожидаю, что операция преуспеет более чем в половине случаев, я бы просто использовал EAFP, конечно, пока у меня не было оснований подозревать, что этот фрагмент кода был фактическим узким местом производительности.