2010-03-26 3 views
47

В another question принятый ответ предложил заменить (очень дешевый) оператор if в коде Python блоком try/except для повышения производительности.Стоимость обработчиков исключений в Python

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

+6

Когда вы измерили его, что вы узнали? –

+1

Связанный вопрос: http://stackoverflow.com/questions/1835756/ – tzot

+0

Используйте try/except, если шансы на управление будут за исключением части меньше, а если/else, если шансов больше. – shadow0359

ответ

67

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

ОК, так что я просто попытался следующее:

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 значительно быстрее.

+1

Интересно. Поэтому 'try/except' быстрее, чем' if a! = 0' – Thilo

+0

@Thilo: Пожалуйста, не спрашивайте. Проделайте еще одно измерение и опубликуйте результаты. –

+13

@S. Лотт: Что ты имеешь в виду? Он не спросил, он сделал заявление. Однако я изменил свой код с 'if a! = 0:' на 'if a:' после того, как он написал свой комментарий (и, кстати, это не повлияло на производительность). Возможно, это причина непонимания? –

33

Этот вопрос на самом деле ответил в Design and History FAQ:

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

+2

Мне просто интересно, насколько эффективен «чрезвычайно эффективный». По-видимому, это быстрее, чем даже очень простое утверждение «если». – Thilo

+0

Выдержка, которую вы опубликовали, из [FAQ по дизайну и истории] (http://docs.python.org/faq/design.html). – nitsas

9

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

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

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

Смежные вопросы