在if语句中使用和使用多个if语句之间是否存在效率差异?换句话说,就像是
if expr1 == expr2 and expr3==expr4:
dostuff()
与效率的观点不同:
if expr1 == expr2:
if expr3 == expr4:
dostuff()
我的基本测试并没有发现差异,但有更多知识(或至少更彻底的测试)的人是否有明确的答案?
答案 0 :(得分:14)
这不足以影响您的决定的性能差异(如果有的话)。 IMO,这里的决定应该纯粹从可读性的角度出发。我认为第一个通常更标准,但有些情况下第二个可能更清晰。选择最能实现您意图的方法。
答案 1 :(得分:11)
使用and
和嵌套ifs之间的速度差异将是最小的。你正在咆哮错误的树。考虑这棵树:
if oftenTrueCondition and rarelyTrueCondition:
与
比较if rarelyTrueCondition and oftenTrueCondition:
因此,除非必须首先评估第一个条件(防止下一个表达式崩溃或做一些愚蠢/昂贵的事情),否则请考虑交换评估顺序。
答案 2 :(得分:4)
在任何一种情况下,expr1 == expr2
评估为false
中的if
,第二项不会被评估。
答案 3 :(得分:4)
如果有疑问,可以使用dis模块检查python编译语句的内容:
>>> 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字节码级别,两个语句都是相同的 - 即使在第一个语句中使用single if时,它也会在第一次比较后执行JUMP_IF_FALSE。
答案 4 :(得分:2)
第一个(if
一个and
)更快: - )
我使用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)