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

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

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

Ответы [ 6 ]

13 голосов
/ 18 января 2011

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

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

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

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

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

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

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

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

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

(я не могу говорить за PHP.)

7 голосов
/ 17 января 2011

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

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

3 голосов
/ 17 января 2011

Великий Алекс Мартелли дает хороший обзор EAFP vs. LBYL в книге «Питон в двух словах».(Он сильно склоняется к использованию EAFP)

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

2 голосов
/ 18 января 2011

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

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

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

0 голосов
/ 18 января 2011

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

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

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

Вот отличная статья по обработке исключений Я сталкивался.

0 голосов
/ 17 января 2011

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

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

...