在python中,为什么if-rank:比if-rank快!=0:
当我改变在python中,为什么if-rank:比if-rank快!=0:,python,performance,numpy,Python,Performance,Numpy,当我改变 for i in range(0, 100): rank = ranks[i] if rank != 0: pass 致: 我发现第二个代码更有效,为什么 基准点,在我的情况下,秩是一个整数的numpy数组。差别要大得多 import numpy as np import time N = 1000000 ranks = np.random.random_integers(0, 10, N) start = time.time() for i in r
for i in range(0, 100):
rank = ranks[i]
if rank != 0:
pass
致:
我发现第二个代码更有效,为什么
基准点,在我的情况下,秩是一个整数的numpy数组。差别要大得多
import numpy as np
import time
N = 1000000
ranks = np.random.random_integers(0, 10, N)
start = time.time()
for i in range(0, N):
rank = ranks[i]
if rank != 0:
pass
print time.time() - start
start = time.time()
for i in range(0, N):
rank = ranks[i]
if rank:
pass
print time.time() - start
start = time.time()
for i in range(0, N):
if i != 0:
pass
print time.time() - start
start = time.time()
for i in range(0, N):
if i:
pass
print time.time() - start
输出:
1.15917396545
0.45020198822
0.123136997223
0.122531175613
将支票提取到核心
for i in range(0,100):
if i != 0:
pass
及
我们看到了不同
$ python -m timeit 'for i in range(0,100):' ' if i != 0:' ' pass'
100000 loops, best of 3: 4.69 usec per loop
$ python -m timeit 'for i in range(0,100):' ' if i:' ' pass'
100000 loops, best of 3: 4.18 usec per loop
不同之处在于,第一种情况涉及比较零,第二种情况只是测试是否为假
要查看它正在做什么,请使用:
>>def():
... 对于范围(0100)内的i:
... 如果我:
... 通过
...
>>>def g():
... 对于范围(0100)内的i:
... 如果我0:
... 通过
...
>>>从dis导入dis
>>>dis(f)
2 0设置环路32(至35)
3加载\u全局0(范围)
6负载常数1(0)
9荷载常数2(100)
12调用函数2
15获得
>>国际热核聚变实验堆15(至34)16
19商店快速0(i)
3 22加载速度0(i)
25如果为假,则弹出跳转16
4 28跳跃式绝对16
31绝对值16
>>34波普卢大厦
>>35负载常数0(无)
38返回值
>>>dis(g)
2 0设置环路38(至41)
3加载\u全局0(范围)
6负载常数1(0)
9荷载常数2(100)
12调用函数2
15获得
>>国际热核聚变实验堆21(至40)16
19商店快速0(i)
3 22加载速度0(i)
25负载常数1(0)40 POP_块
>>41负载常数0(无)
44返回值
你是怎么发现的?你做过基准测试吗?我希望有一点提升,因为在解释型Python中进行的工作较少,而在内置方法中进行的工作较多,但在实际程序中,这可能不会很大。(这仍然值得一做,因为它是标准样式,代码更少。)在我的情况下,秩是一个整数数组numpy。差异似乎更大。如果您dis
这两个示例,差异仍然是LOAD_CONST 1(0)
和COMPARE_OP 3(!=)
。但是,如果将If
替换为i==True
,如何解释?后者更为公平slower@sza很简单,True
是全局的,因此python执行操作LOAD\u global
,而不是Py2k中的LOAD\u CONST
,您可以执行True,False=False,True
,这使得False==not True
,但是False
现在是True
,True
现在是False
。
for i in range(0,100):
if i:
pass
$ python -m timeit 'for i in range(0,100):' ' if i != 0:' ' pass'
100000 loops, best of 3: 4.69 usec per loop
$ python -m timeit 'for i in range(0,100):' ' if i:' ' pass'
100000 loops, best of 3: 4.18 usec per loop
>>> def f():
... for i in range(0,100):
... if i:
... pass
...
>>> def g():
... for i in range(0,100):
... if i != 0:
... pass
...
>>> from dis import dis
>>> dis(f)
2 0 SETUP_LOOP 32 (to 35)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (100)
12 CALL_FUNCTION 2
15 GET_ITER
>> 16 FOR_ITER 15 (to 34)
19 STORE_FAST 0 (i)
3 22 LOAD_FAST 0 (i)
25 POP_JUMP_IF_FALSE 16
4 28 JUMP_ABSOLUTE 16
31 JUMP_ABSOLUTE 16
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
>>> dis(g)
2 0 SETUP_LOOP 38 (to 41)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (100)
12 CALL_FUNCTION 2
15 GET_ITER
>> 16 FOR_ITER 21 (to 40)
19 STORE_FAST 0 (i)
3 22 LOAD_FAST 0 (i)
25 LOAD_CONST 1 (0) <-- this only happens in != 0
28 COMPARE_OP 3 (!=) <-- this only happens in != 0
31 POP_JUMP_IF_FALSE 16
4 34 JUMP_ABSOLUTE 16
37 JUMP_ABSOLUTE 16
>> 40 POP_BLOCK
>> 41 LOAD_CONST 0 (None)
44 RETURN_VALUE