5

私が変わったとき

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

2 番目のコードの方がはるかに効率的であることがわかりました。なぜですか?

それをベンチマークしてください。私の状況では、ランクは整数の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
4

1 に答える 1

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

違いは、最初のケースではゼロとの比較が含まれるのに対し、2 番目のケースでは false かどうかをテストするだけであるということです。

何をしているかを見るには、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
于 2013-08-05T03:11:11.960 に答える