Стоимость обработчиков исключений в Python - PullRequest
69 голосов
/ 26 марта 2010

В другой вопрос , в принятом ответе предлагается заменить (очень дешевый) оператор if в коде Python на блок try / исключением для повышения производительности.

Проблемы стиля кодирования остались в стороне, и, предполагая, что исключение никогда не сработало, насколько сильно (с точки зрения производительности) имеет обработчик исключения, а не тот, который имеет оператор сравнения с нулем if

Ответы [ 3 ]

88 голосов
/ 26 марта 2010

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

ОК, поэтому я только что попробовал следующее:

import timeit

statements=["""\
try:
    b = 10/a
except ZeroDivisionError:
    pass""",
"""\
if a:
    b = 10/a""",
"b = 10/a"]

for a in (1,0):
    for s in statements:
        t = timeit.Timer(stmt=s, setup='a={}'.format(a))
        print("a = {}\n{}".format(a,s))
        print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))

Результат:

a = 1
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.25 usec/pass

a = 1
if a:
    b = 10/a
0.29 usec/pass

a = 1
b = 10/a
0.22 usec/pass

a = 0
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.57 usec/pass

a = 0
if a:
    b = 10/a
0.04 usec/pass

a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero

Таким образом, как и ожидалось, отсутствие какого-либо обработчика исключений немного быстрее (но взрывается, когда возникает исключение), и try/except быстрее, чем явный if, если условие не выполняется.

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

46 голосов
/ 27 марта 2010

На этот вопрос действительно дан ответ в FAQ по дизайну и истории :

Блок try / исключения чрезвычайно эффективен, если не возникает никаких исключений. На самом деле ловить исключение дорого.

14 голосов
/ 19 сентября 2010

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

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

Если вы используете исключение как часть стандартного потока управления - то есть, как Pythonic «просить прощение, а не разрешение» - тогда исключение будет вызвано, и стоимость зависит от вида исключения, вроде как, и в каком проценте времени вы оцениваете исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...