Python 就效率/快速拒绝问题而言,如果您的if语句在同一行上,这是否重要?
例如,假设我想找到1到1000之间所有可以被3和5整除的数字。守则可否:Python 就效率/快速拒绝问题而言,如果您的if语句在同一行上,这是否重要?,python,performance,processing-efficiency,Python,Performance,Processing Efficiency,例如,假设我想找到1到1000之间所有可以被3和5整除的数字。守则可否: for i in range(1,1000): if i % 3==0 and i %5 == 0: blah 不如说 for i in range(1,1000): if i%3==0: if i%5==0: blah 计算机是否检查这两种情况?例如,如果i=10。第一台计算机会同时计算i%3和i%5,还是会计算i%3然后中断?在这种情况下,将易于检
for i in range(1,1000):
if i % 3==0 and i %5 == 0:
blah
不如说
for i in range(1,1000):
if i%3==0:
if i%5==0:
blah
计算机是否检查这两种情况?例如,如果i=10。第一台计算机会同时计算i%3和i%5,还是会计算i%3然后中断?在这种情况下,将易于检查/拒绝的条件放在左侧会更有效,对吗?否,一旦其中一个条件为false,它将返回false。这叫做短路。请参阅。在python和许多语言中,布尔表达式都有一个完整的定义。这意味着一旦我们确定布尔表达式的真值,计算就会停止。在这方面,两个代码片段是等效的 但是,您可以通过更改顺序进行优化。例如,最好使用:
if i % 5 == 0 and i % 3 == 0
原因是一个数字很少是5的倍数,所以在大多数情况下,这个表达式会更早失败
例如,如果我们检查从1到150的数字,检查
i%5==0
将失败120个数字。因此,我们将对i%5==0
执行120次检查,对i%5==0
和i%3==0
执行30次检查。这总共是180张支票。类似地,对于如果i%3==0和i%5==0,我们将执行100+2*50=200
检查。除了解释短路的其他答案之外,这两个答案都做一项工作,性能之间没有太大差异
请参见以下基准:
s1="""
for i in range(1,1000):
if i % 3==0 and i %5 == 0:
pass
"""
s2="""
for i in range(1,1000):
if i%3==0:
if i%5==0:
pass
"""
print ' first: ' ,timeit(stmt=s1, number=1000)
print 'second : ',timeit(stmt=s2, number=1000)
结果:
first: 0.0738339424133
second : 0.0790829658508
正如您所看到的,差异是0.006
,这是因为第二部分中有一个额外的块加载
您还可以使用dis
模块来分解python字节码:
使用和的第一个循环:
21 0 SETUP_LOOP 58 (to 61)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (1)
9 LOAD_CONST 2 (1000)
12 CALL_FUNCTION 2
15 GET_ITER
>> 16 FOR_ITER 41 (to 60)
19 STORE_FAST 0 (i)
22 22 LOAD_FAST 0 (i)
25 LOAD_CONST 3 (3)
28 BINARY_MODULO
29 LOAD_CONST 4 (0)
32 COMPARE_OP 2 (==)
35 POP_JUMP_IF_FALSE 16
38 LOAD_FAST 0 (i)
41 LOAD_CONST 5 (5)
44 BINARY_MODULO
45 LOAD_CONST 4 (0)
48 COMPARE_OP 2 (==)
51 POP_JUMP_IF_FALSE 16
23 54 JUMP_ABSOLUTE 16
57 JUMP_ABSOLUTE 16
>> 60 POP_BLOCK
>> 61 LOAD_CONST 0 (None)
64 RETURN_VALUE
第二点:
26 0 SETUP_LOOP 61 (to 64)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (1)
9 LOAD_CONST 2 (1000)
12 CALL_FUNCTION 2
15 GET_ITER
>> 16 FOR_ITER 44 (to 63)
19 STORE_FAST 0 (i)
27 22 LOAD_FAST 0 (i)
25 LOAD_CONST 3 (3)
28 BINARY_MODULO
29 LOAD_CONST 4 (0)
32 COMPARE_OP 2 (==)
35 POP_JUMP_IF_FALSE 16
28 38 LOAD_FAST 0 (i)
41 LOAD_CONST 5 (5)
44 BINARY_MODULO
45 LOAD_CONST 4 (0)
48 COMPARE_OP 2 (==)
51 POP_JUMP_IF_FALSE 60
29 54 JUMP_ABSOLUTE 60
57 JUMP_ABSOLUTE 16
>> 60 JUMP_ABSOLUTE 16
>> 63 POP_BLOCK
>> 64 LOAD_CONST 0 (None)
67 RETURN_VALUE
我还学到了一个新短语,短路,谢谢@jornsharpeoh,很简单。每种语言都是一样的吗?我不确定“每种”语言,但这里列出了一些@avid19某些语言需要不同语法的语言-例如在VB.NET中,基本和和和或不短路,而是和和或执行。这就是我的想法,快速拒绝总是更好的。谢谢-1,这两个表达式的组合是相同的。时间上的任何差异都是由于测试环境的差异和不可靠性造成的。@NickBastin我认为这表明,他们说“性能之间没有太大差异”。@NickBastin正如avid19所说,我没有说没有任何差异!检查编辑!