program story

while 루프를 사용하는 것보다 파이썬에서 range ()를 반복하는 것이 왜 더 빠릅니까?

inputbox 2020. 10. 31. 09:40
반응형

while 루프를 사용하는 것보다 파이썬에서 range ()를 반복하는 것이 왜 더 빠릅니까?


다른 날 파이썬 벤치마킹을하던 중 흥미로운 것을 발견했습니다. 다음은 거의 동일한 작업을 수행하는 두 개의 루프입니다. 루프 1은 실행하는 데 루프 2의 약 두 배가 걸립니다.

루프 1 :

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

루프 2 :

for n in range(0,100000000):
  pass

첫 번째 루프가 왜 그렇게 느린가요? 나는 그것이 사소한 예라는 것을 알고 있지만 그것은 내 관심을 불러 일으켰습니다. 같은 방식으로 변수를 증가시키는 것보다 더 효율적으로 만드는 range () 함수에 특별한 것이 있습니까?


파이썬 바이트 코드의 분해를 보면 좀 더 구체적인 아이디어를 얻을 수 있습니다.

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 개의 op가 있습니다.

사용 범위 :

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 코드를 실행하는 시간은 정수기보다 훨씬 짧으며 무시할 수 있습니다.


range()C로 구현되지만 i += 1해석됩니다.

사용하면 xrange()많은 수의 경우 더 빨리 만들 수 있습니다. Python 3.0부터는 range()이전과 동일합니다 xrange().


while 루프에서 많은 객체 생성 및 파괴가 진행되고 있다고 말해야합니다.

i += 1

와 같다:

i = i + 1

그러나 Python int는 변경 불가능하기 때문에 기존 객체를 수정하지 않습니다. 오히려 그것은 새로운 가치를 가진 새로운 물건을 창조합니다. 기본적으로 다음과 같습니다.

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

가비지 수집기는 또한 많은 양의 정리 작업을 수행해야합니다. "객체 생성은 비싸다".


인터프리터에서 C로 작성된 코드로 더 자주 실행되기 때문입니다. 즉, i + = 1은 Python에 있으므로 (비교적으로) 느리지 만 range (0, ...)은 하나의 C 호출이며 for 루프는 대부분 C에서도 실행됩니다.


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.

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

반응형