다음 두 코드 스 니펫간에 궁극적 인 차이점이 있습니까? 첫 번째는 함수의 변수에 값을 할당 한 다음 해당 변수를 반환합니다. 두 번째 함수는 값을 직접 반환합니다.
파이썬은 그것들을 동등한 바이트 코드로 바꾸나요? 그들 중 하나가 더 빠릅니까?
사례 1 :
def func():
a = 42
return a
사례 2 :
def func():
return 42
다음 두 코드 스 니펫간에 궁극적 인 차이점이 있습니까? 첫 번째는 함수의 변수에 값을 할당 한 다음 해당 변수를 반환합니다. 두 번째 함수는 값을 직접 반환합니다.
파이썬은 그것들을 동등한 바이트 코드로 바꾸나요? 그들 중 하나가 더 빠릅니까?
사례 1 :
def func():
a = 42
return a
사례 2 :
def func():
return 42
답변:
아니요, 그렇지 않습니다 .
CPython 바이트 코드에 대한 컴파일은 기본 최적화 만 수행하도록 설계된 작은 구멍 최적화 프로그램 을 통해서만 전달됩니다 ( 이러한 최적화에 대한 자세한 내용은 테스트 스위트의 test_peepholer.py 참조 ).
실제로 일어날 일 dis
을 살펴 보려면 *를 사용하여 생성 된 지침을 확인하십시오. 할당을 포함하는 첫 번째 함수의 경우 :
from dis import dis
dis(func)
2 0 LOAD_CONST 1 (42)
2 STORE_FAST 0 (a)
3 4 LOAD_FAST 0 (a)
6 RETURN_VALUE
두 번째 기능의 경우 :
dis(func2)
2 0 LOAD_CONST 1 (42)
2 RETURN_VALUE
두 개의 (빠른) 명령어가 첫 번째에 사용됩니다 : STORE_FAST
및 LOAD_FAST
. 이것들 fastlocals
은 현재 실행 프레임 의 배열에있는 값을 빠르게 저장하고 잡습니다 . 그런 다음 두 경우 모두 a RETURN_VALUE
가 수행됩니다. 따라서 두 번째는 실행하는 데 필요한 명령이 적기 때문에 약간 더 빠릅니다.
일반적으로 CPython 컴파일러는 수행하는 최적화에서 보수적 이라는 점에 유의하십시오 . 그것은하지 않고 일을 시도하지 않습니다 (일반적으로, 또한 작업에 더 많은 정보를 가지고) 다른 컴파일러 스마트한다. 명백히 올바른 것 외에 주요 디자인 목표는 a) 단순하게 유지하고 b) 컴파일 단계가 존재한다는 사실조차 알지 못하도록 최대한 신속하게 컴파일하는 것입니다.
결국, 이와 같은 사소한 문제로 고민해서는 안됩니다. 속도의 이점은 작고 일정하며 Python이 해석된다는 사실로 인해 발생하는 오버 헤드로 인해 왜소합니다.
* dis
는 코드를 분해하는 작은 Python 모듈입니다.이를 사용하여 VM이 실행할 Python 바이트 코드를 볼 수 있습니다.
참고 : @Jorn Vernee의 주석에서도 언급했듯이 이것은 Python의 CPython 구현에만 해당됩니다. 다른 구현은 원하는 경우 더 적극적인 최적화를 수행 할 수 있지만 CPython은 그렇지 않습니다.
둘 다 기본적으로 동일하지만 첫 번째 경우 객체 42
가 단순히 이름이 지정된 변수에 할당 a
되거나, 즉 이름 (즉 a
)이 값 (예 42
)을 참조 한다는 점을 제외하면 동일합니다 . 데이터를 복사하지 않는다는 점에서 기술적으로 어떤 할당도하지 않습니다.
return
ing 동안 이 명명 된 바인딩 a
은 첫 번째 경우 42
에 반환되고 개체 는 두 번째 경우에 반환됩니다.
자세한 내용은 Ned Batchelder의 훌륭한 기사를 참조하십시오.
dis.dis(..)
둘 다 사용 하면 차이 가 있음 을 알 수 있으므로 그렇습니다. 그러나 대부분의 실제 응용 프로그램에서 함수 처리 지연에 비해이 오버 헤드는 그다지 많지 않습니다.