Эффективность Python для нескольких ifs и против них

Есть ли разница в эффективности между использованием d в операторе if и с использованием нескольких операторов if? Другими словами, отличается ли что-то вроде

if expr1 == expr2 and expr3==expr4:
  dostuff()

с точки зрения эффективности:

if expr1 == expr2:
  if expr3 == expr4:
    dostuff()

Мое самое базовое тестирование не выявляет разницы, но есть ли у кого-то с более глубокими знаниями (или, по крайней мере, более тщательное тестирование) окончательный ответ?

14
задан froadie 20 August 2010 в 17:51
поделиться

5 ответов

В любом случае expr1 == expr2 оценивается в false в if, второе не будет оценено.

4
ответ дан 1 December 2019 в 07:26
поделиться

Первый (один , если с и ) быстрее: -)

Я пробовал использовать timeit . Вот результаты:

Variant 1: 9.82836714316
Variant 2: 9.83886494559
Variant 1 (True): 9.66493159804
Variant 2 (True): 10.0392633241

Для последних двух первое сравнение - True , поэтому второе сравнение пропускается. Интересные результаты.


import timeit


print "Variant 1: %s" % timeit.timeit("""
for i in xrange(1000):
    if i == 2*i and i == 3*i:
        pass
        """,
        number = 1000)

print "Variant 2: %s" % timeit.timeit("""
for i in xrange(1000):
    if i == 2*i:
        if i == 3*i:
            pass
        """,
        number = 1000)

print "Variant 1 (True): %s" % timeit.timeit("""
for i in xrange(1000):
    if i == i and i == 3*i:
        pass
        """,
        number = 1000)

print "Variant 2 (True): %s" % timeit.timeit("""
for i in xrange(1000):
    if i == i:
        if i == 3*i:
            pass
        """,
        number = 1000)
2
ответ дан 1 December 2019 в 07:26
поделиться

Этого различия в производительности недостаточно, чтобы повлиять на ваше решение. ИМО, решение здесь следует принимать исключительно с точки зрения удобочитаемости. Я думаю, что первое в целом более стандартно, но бывают ситуации, когда второе может быть более понятным. Выберите метод, который лучше всего передает ваше намерение.

14
ответ дан 1 December 2019 в 07:26
поделиться

Любые различия в скорости между использованием и и вложенными if будут минимальными. Вы лаете не на то дерево. Рассмотрим это дерево:

if oftenTrueCondition and rarelyTrueCondition:

по сравнению с

if rarelyTrueCondition and oftenTrueCondition:

Итак, если первое условие не должно быть оценено первым (это защита, чтобы предотвратить сбой следующего выражения или сделать что-то глупое / дорогое), подумайте об изменении порядка оценки.

11
ответ дан 1 December 2019 в 07:26
поделиться

Если вы сомневаетесь, вы можете проверить, что python компилирует ваши операторы, используя модуль dis:

>>> import dis
>>> def test1():
...     if expr1 == expr2 and expr3==expr4:
...        dostuff()
... 
>>> def test2():
...     if expr1 == expr2:
...        if expr3 == expr4:
...           dostuff()
... 
>>> dis.dis(test1)
  2           0 LOAD_GLOBAL              0 (expr1)
              3 LOAD_GLOBAL              1 (expr2)
              6 COMPARE_OP               2 (==)
              9 JUMP_IF_FALSE           24 (to 36)
             12 POP_TOP             
             13 LOAD_GLOBAL              2 (expr3)
             16 LOAD_GLOBAL              3 (expr4)
             19 COMPARE_OP               2 (==)
             22 JUMP_IF_FALSE           11 (to 36)
             25 POP_TOP             

  3          26 LOAD_GLOBAL              4 (dostuff)
             29 CALL_FUNCTION            0
             32 POP_TOP             
             33 JUMP_FORWARD             1 (to 37)
        >>   36 POP_TOP             
        >>   37 LOAD_CONST               0 (None)
             40 RETURN_VALUE        
>>> dis.dis(test2)
  2           0 LOAD_GLOBAL              0 (expr1)
              3 LOAD_GLOBAL              1 (expr2)
              6 COMPARE_OP               2 (==)
              9 JUMP_IF_FALSE           28 (to 40)
             12 POP_TOP             

  3          13 LOAD_GLOBAL              2 (expr3)
             16 LOAD_GLOBAL              3 (expr4)
             19 COMPARE_OP               2 (==)
             22 JUMP_IF_FALSE           11 (to 36)
             25 POP_TOP             

  4          26 LOAD_GLOBAL              4 (dostuff)
             29 CALL_FUNCTION            0
             32 POP_TOP             
             33 JUMP_ABSOLUTE           41
        >>   36 POP_TOP             
             37 JUMP_FORWARD             1 (to 41)
        >>   40 POP_TOP             
        >>   41 LOAD_CONST               0 (None)
             44 RETURN_VALUE        

Итак, как вы можете видеть, на уровне байт-кода python оба оператора одинаковы - даже если вы используете единственный оператор if at first , он выполнит JUMP_IF_FALSE после первого сравнения.

5
ответ дан 1 December 2019 в 07:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: