programing

(1) vs (True) -- (python 2 바이트 코드에서) 왜 차이가 나죠?

telebox 2023. 10. 4. 21:15
반응형

(1) vs (True) -- (python 2 바이트 코드에서) 왜 차이가 나죠?

펄의 무한 루프에 대한 이 질문에 흥미를 느낍니다: (1) Vs. for(;;;) 속도 차이가 있습니까?파이썬에서도 비슷한 비교를 해보기로 했습니다.컴파일러가 동일한 바이트 코드를 생성할 것으로 예상했습니다.while(True): pass그리고.while(1): pass, 그러나 python 2.7에서는 실제로 그렇지 않습니다.

다음 스크립트:

import dis

def while_one():
    while 1:
        pass

def while_true():
    while True:
        pass

print("while 1")
print("----------------------------")
dis.dis(while_one)

print("while True")
print("----------------------------")
dis.dis(while_true)

은(는) 다음과 같은 결과를 가져옵니다.

while 1
----------------------------
  4           0 SETUP_LOOP               3 (to 6)

  5     >>    3 JUMP_ABSOLUTE            3
        >>    6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        
while True
----------------------------
  8           0 SETUP_LOOP              12 (to 15)
        >>    3 LOAD_GLOBAL              0 (True)
              6 JUMP_IF_FALSE            4 (to 13)
              9 POP_TOP             

  9          10 JUMP_ABSOLUTE            3
        >>   13 POP_TOP             
             14 POP_BLOCK           
        >>   15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        

사용.while True눈에 띄게 더 복잡합니다왜 이러한가?

다른 맥락에서 python은 마치True1과 같음:

>>> True == 1
True

>>> True + True
2

왜 그럴까요?while그 둘을 구별할 수 있습니까?

python3가 동일한 연산을 사용하여 문을 평가한다는 것을 알게 되었습니다.

while 1
----------------------------
  4           0 SETUP_LOOP               3 (to 6) 

  5     >>    3 JUMP_ABSOLUTE            3 
        >>    6 LOAD_CONST               0 (None) 
              9 RETURN_VALUE         
while True
----------------------------
  8           0 SETUP_LOOP               3 (to 6) 

  9     >>    3 JUMP_ABSOLUTE            3 
        >>    6 LOAD_CONST               0 (None) 
              9 RETURN_VALUE         

python3에 부울 평가 방식에 변화가 있습니까?

파이썬 2.x에서는,True키워드가 아니라 단지 내장된 전역 상수로 정의됩니다.booltype. 따라서 인터프리터는 여전히 내용을 로드해야 합니다.True. 즉,True는 재할당 가능합니다.

Python 2.7 (r27:82508, Jul  3 2010, 21:12:11) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
>>> True
4

Python 3.x에서는 실제로 키워드와 실제 상수가 됩니다.

Python 3.1.2 (r312:79147, Jul 19 2010, 21:03:37) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
  File "<stdin>", line 1
SyntaxError: assignment to keyword

따라서 인터프리터는 대체할 수 있습니다.while True:무한 순환 고리

그것을 "무한 루프"라고 부르는 것은 옳지 않습니다.

따라서 인터프리터는 while True: 루프를 무한 루프로 대체할 수 있습니다.

아직 그런 상황에서 벗어날 수 있기 때문에while True:고리. 하지만 그런 고리는elsepython 3에서는 절에 접근할 수 없습니다.

그리고 Python 3의 가치 조회를 단순화함으로써True실행 속도가 매우 빠릅니다.while 1파이썬 2에서.

성능비교

루프를 하는 동안 다소 사소하지 않은 시간의 차이를 보여줍니다.

세우다

def while1():
    x = 0
    while 1:
        x += 1
        if x == 10:
            break
            
def whileTrue():
    x = 0
    while True:
        x += 1
        if x == 10:
            break

파이썬 2

>>> import timeit
>>> min(timeit.repeat(while1))
0.49712109565734863
>>> min(timeit.repeat(whileTrue))
0.756627082824707

파이썬 3

>>> import timeit
>>> min(timeit.repeat(while1))
0.6462970309949014
>>> min(timeit.repeat(whileTrue))
0.6450748789939098

설명.

차이점을 설명하자면, 파이썬 2에서:

>>> import keyword
>>> 'True' in keyword.kwlist
False

그러나 파이썬 3에서는:

>>> import keyword
>>> 'True' in keyword.kwlist
True
>>> True = 'true?'
  File "<stdin>", line 1
SyntaxError: can't assign to keyword

부터True는 파이썬 3의 키워드입니다. 인터프리터는 누군가 다른 값으로 대체했는지 확인하기 위해 값을 조회할 필요가 없습니다.하지만 한 사람이 지정할 수 있기 때문에TruePython 2의 또 다른 값으로, 인터프리터는 매번 찾아야 합니다.

파이썬 2의 결론

파이썬 2의 루프가 촘촘하고 오래 지속된다면 다음과 같은 방법을 사용해야 합니다.while 1:대신에while True:.

파이썬 3의 결론

사용하다while True:만일 당신이 당신의 고리에서 벗어날 수 있는 조건이 없다면.

이것은 이미 훌륭한 답을 가지고 있는 7살짜리 질문이지만, 어떤 답에서도 다루지 않은 질문의 잘못된 개념은 중복으로 표시된 다른 질문들을 혼란스럽게 할 가능성이 있습니다.

다른 맥락에서 python은 True가 1인 것처럼 작용합니다.

>>> True == 1
True

>>> True + True
2

왜 두 가지를 구별하는 것입니까?

.while여기선 전혀 다른 일을 하고 있지 않습니다그것은 구별됩니다.1그리고.True+예를 들어 그렇습니다.


여기 2.7:

>>> dis.dis('True == 1')
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_CONST               1 (1)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE

>>> dis.dis('True == 1')
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              0 (True)
              6 BINARY_ADD
              9 RETURN_VALUE

이제 비교:

>>> dis.dis('1 + 1')
  1           0 LOAD_CONST               1 (2)
              3 RETURN_VALUE

있습니다.LOAD_GLOBAL (True)True, 옵티마이저가 할 수 있는 일은 지구 전체에 대해서는 아무 것도 없습니다. 그래서,while이 있는1그리고.True+합니다. (그리고==최적화 도구가 비교를 최적화하지 않기 때문에 이들을 구분하지 못합니다.)


이제 3.6을 비교합니다.

>>> dis.dis('True == 1')
  1           0 LOAD_CONST               0 (True)
              2 LOAD_CONST               1 (1)
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

>>> dis.dis('True + True')
  1           0 LOAD_CONST               1 (2)
              2 RETURN_VALUE

여기서, 이것은 방출되고 있습니다.LOAD_CONST (True)최적화자가 활용할 수 있는 키워드에 대한 정보를 제공합니다.True + 1 정확히 같은 이유로 구별하지는 않습니다.while True안 그래요. (그리고)==최적화 도구가 비교를 최적화하지 못하기 때문에 여전히 이들을 구분하지 못합니다.)


는 결국 하게 됩니다.True그리고.1이 세가지 경우 모두 똑같습니다.bool의 하위 클래스입니다.int를 합니다.int,그리고.True내부 1다를 그래서, 당신이 그 일을 하고 있는지 아닌지는while테스트()__bool__ 3.x에서__nonzero__2.x),교(__eq__ 또는 (,()__add__를 하든 사용하든 입니다. 를입니다.True아니면1.

언급URL : https://stackoverflow.com/questions/3815359/while-1-vs-whiletrue-why-is-there-a-difference-in-python-2-bytecode

반응형