当我改变时
for i in range(0, 100):
rank = ranks[i]
if rank != 0:
pass
为:
for i in range(0, 100):
rank = ranks[i]
if rank:
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
答案 0 :(得分:8)
将支票提炼到核心
for i in range(0,100):
if i != 0:
pass
和
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
不同之处在于,虽然第一种情况涉及比较为零,但第二种情况只是测试是否为假。
要了解它的作用,请使用dis:
>>> 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