Why is looping over range() in Python faster than using a while loop?

六眼飞鱼酱① 提交于 2019-12-17 03:27:06

问题


The other day I was doing some Python benchmarking and I came across something interesting. Below are two loops that do more or less the same thing. Loop 1 takes about twice as long as loop 2 to execute.

Loop 1:

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

Loop 2:

for n in range(0,100000000):
  pass

Why is the first loop so much slower? I know it's a trivial example but it's piqued my interest. Is there something special about the range() function that makes it more efficient than incrementing a variable the same way?


回答1:


see the disassembly of python byte code, you may get a more concrete idea

use while loop:

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

The loop body has 10 op

use range:

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

The loop body has 3 op

The time to run C code is much shorter than intepretor and can be ignored.




回答2:


range() is implemented in C, whereas i += 1 is interpreted.

Using xrange() could make it even faster for large numbers. Starting with Python 3.0 range() is the same as previously xrange().




回答3:


It must be said that there is a lot of object creation and destruction going on with the while loop.

i += 1

is the same as:

i = i + 1

But because Python ints are immutable, it doesn't modify the existing object; rather it creates a brand new object with a new value. It's basically:

i = new int(i + 1)   # Using C++ or Java-ish syntax

The garbage collector will also have a large amount of cleanup to do. "Object creation is expensive".




回答4:


Because you are running more often in code written in C in the interpretor. i.e. i+=1 is in Python, so slow (comparatively), whereas range(0,...) is one C call the for loop will execute mostly in C too.




回答5:


Most of Python's built in method calls are run as C code. Code that has to be interpreted is much slower. In terms of memory efficiency and execution speed the difference is gigantic. The python internals have been optimized to the extreme, and it's best to take advantage of those optimizations.



来源:https://stackoverflow.com/questions/869229/why-is-looping-over-range-in-python-faster-than-using-a-while-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!