1. ホーム
  2. python

[解決済み] なぜPythonのrange()ループはwhileループより速いのか?

2023-05-17 19:49:49

疑問点

先日、Pythonのベンチマークを行っていたところ、面白いことに遭遇しました。 以下は、多かれ少なかれ同じことを行う2つのループです。 ループ1はループ2の約2倍の時間をかけて実行されます。

ループ 1 です。

int i = 0
while i < 100000000:
  i += 1

ループ2

for n in range(0,100000000):
  pass

なぜ最初のループはこれほど遅いのでしょうか? つまらない例ですが、興味をそそられました。 range()関数には、同じ方法で変数をインクリメントするよりも効率的な特別な何かがあるのでしょうか?

どのように解決するのですか?

Pythonのバイトコードの逆アセンブルを見ると、より具体的なアイデアが浮かぶかもしれません。

whileループを使用する。

1           0 LOAD_CONST               0 (0)
            3 STORE_NAME               0 (i)

2           6 SETUP_LOOP              28 (to 37)
      >>    9 LOAD_NAME                0 (i)              # <-
           12 LOAD_CONST               1 (100000000)      # <-
           15 COMPARE_OP               0 (<)              # <-
           18 JUMP_IF_FALSE           14 (to 35)          # <-
           21 POP_TOP                                     # <-

3          22 LOAD_NAME                0 (i)              # <-
           25 LOAD_CONST               2 (1)              # <-
           28 INPLACE_ADD                                 # <-
           29 STORE_NAME               0 (i)              # <-
           32 JUMP_ABSOLUTE            9                  # <-
      >>   35 POP_TOP
           36 POP_BLOCK

ループ本体は10オペ

を使用する範囲です。

1           0 SETUP_LOOP              23 (to 26)
            3 LOAD_NAME                0 (range)
            6 LOAD_CONST               0 (0)
            9 LOAD_CONST               1 (100000000)
           12 CALL_FUNCTION            2
           15 GET_ITER
      >>   16 FOR_ITER                 6 (to 25)        # <-
           19 STORE_NAME               1 (n)            # <-

2          22 JUMP_ABSOLUTE           16                # <-
      >>   25 POP_BLOCK
      >>   26 LOAD_CONST               2 (None)
           29 RETURN_VALUE

ループ本体は3オペ

C言語のコード実行時間はintepretorよりはるかに短く、無視できるほどです。