Является ли обработка исключений python более эффективной, чем PHP и / или другие языки?

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

Теперь, когда я изучаю python, я вижу множество исключений во всем мире и принцип EAFP . Означает ли это, что python более эффективен при обработке исключений, поэтому мне не нужно так беспокоиться о них для управления потоком, или этот принцип все еще стоит? Если нет, то PHP является исключением из нормы (по сравнению с другими языками) или Python?

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

В C ++ работают две вещи:

  • Выбрасывание исключения очень сложно. Стек необходимо разматывать, и сделать это в собственном коде намного сложнее, чем на высокоуровневом языке на основе VM.
  • Регулярное, прямое управление потоком очень быстрое. Это собственный код; ветвь представляет собой пару инструкций, где исключение, отбрасывающее стек, вызывает сложный алгоритм (поиск данных стека в большой, возможно сжатой таблице и т. д.).

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

Это не относится к языкам высокого уровня. Это также по двум причинам:

  • Откат стопки намного проще. Стек очень легко изучить; вам не нужны волшебные таблицы, чтобы знать, как далеко отбросить стек и какие объекты будут построены в любой момент времени.
  • Регулярный поток программ по своей природе медленнее. На языке, основанном на виртуальной машине, все просто требует больше работы.

Исключения все еще не являются бесплатными, но несоответствие уже не является чем-то, о чем можно так беспокоиться. Это означает, что общая мудрость, сформированная на C ++, здесь неверна. Исключения регулярно используются в нормальном потоке программы.

Фактически, они встроены в язык, в конструкции, которые вы используете все время. Каждый раз, когда вы используете итератор – каждый for x in xrange(1000) , для завершения цикла используется исключение StopIteration .

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

(Я не могу говорить для PHP.)

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

Отбрасывание исключений в качестве альтернативы операторам if или корректным инструкциям while или вместо использования break или continue внутри цикла не относится к этой категории. Это ленивый, подверженный ошибкам прогамминг, которого следует избегать.

великий Алекс Мартелли дает хороший обзор EAFP против LBYL в книге «Python In A Nutshell». (Он сильно опирается на использование EAFP)

def worth чтение:
http://books.google.com/books?id=JnR9hQA3SncC&lpg=PA134&ots=JaaWGy-24u&dq=alex%20martelli%20eafp%20lbyl&pg=PA134#v=onepage&q&f=false

Чтобы ответить на вопрос: Да. Исключения на Python дешевы. Если тест по-прежнему дешевле, да, вы должны просто использовать исключения для «неожиданных» ситуаций, так как если бы вы ожидали, что код будет терпеть неудачу чаще всего, проверьте, прежде чем вы это сделаете. Поскольку if-check будет избегать также фактической попытки, а также повышения и улавливания исключения, это будет намного быстрее в ситуации, которая терпит неудачу. (Если, конечно, сам тест не стоит дорого).

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

И как обычно: оптимизация без профилирования преждевременна.

Существует специальное исключение, которое предполагается использовать только в обычном потоке выполнения: StopIteration . Это означает, что создатель Python не считает, что накладные расходы исключений не соответствуют требованиям.

Является ли это потому, что обработка исключений uber-эффективна или остальная часть языка просто медленна путем сравнения – это еще один вопрос …

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

В PHP вы можете обернуть $page->GetContent(); в try...catch блоки все, что вы хотите, но если $page не является объектом, ваше приложение по-прежнему будет зависнуть с результирующей фатальной ошибкой. Поэтому в PHP (и на любом другом языке, где ошибки не могут быть обнаружены), вам нужен определенный уровень LBYL.

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

Вот отличная статья об обработке исключений, с которой я столкнулся.