Python의 dis 모듈: 바이트코드 disassemble하기
Python은 인터프리터 언어지만, 실행 전에 source code (원시코드)를 bytecode (바이트코드) 라는 중간 형태로 컴파일하여 성능을 향상시킴.
- 이 바이트코드는 Python의 가상 머신(보통 CPython VM)에서 실행됨.
- 이를 disassemble(역어셈블)하여 분석할 수 있게 해주는 도구가 표준 라이브러리의
dis
모듈임.
2024.06.05 - [CE] - [CE] Bytecode (바이트코드)
[CE] Bytecode (바이트코드)
Bytecode (바이트코드)정의:Bytecode는 고수준 프로그래밍 언어로 작성된 source code를 중간 형태로 변환한 code 임.이는 특정 Virtual Machine (VM)에서 실행될 수 있도록 설계됨.가장 대표적인 예로 Java에서
ds31x.tistory.com
https://dsaint31.tistory.com/496
[Python] Interpreter and PVM (Python Virtual Machine)
Interpreter and PVM (Python Virtual Machine)더보기대학을 막 졸업해서 초보 프로그래머로 일을 할 때 개인적으로 가지고 있던 편견 중 하나가 script language를 매우 하찮게 생각하면서 오직 compiler language
dsaint31.tistory.com
dis 모듈 소개
dis
모듈은 Python 바이트코드를 '역어셈블(disassemble)'하여 인간이 읽을 수 있는 형태로 보여줌.- 일종의 Assembly Language 처럼 보이는 이 코드를 통해,
- 실제 코드가 어떻게 실행되는지, 내부적으로 어떤 최적화가 이루어지는지 이해할 수 있음.
예제 코드:
import dis
def example():
a = 3
b = 7
return a + b
dis.dis(example)
출력 결과:
2 0 RESUME 0
3 2 LOAD_CONST 1 (3)
4 STORE_FAST 0 (a)
4 6 LOAD_CONST 2 (7)
8 STORE_FAST 1 (b)
5 10 LOAD_FAST 0 (a)
12 LOAD_FAST 1 (b)
14 BINARY_ADD
16 RETURN_VALUE
Bytecode 이해하기
bytecode (바이트코드) 출력을 해석하는 방법은 다음과 같음:
- 첫 번째 열: 소스 코드의 줄 번호
- 두 번째 열: 바이트코드 내 명령어의 오프셋(위치)
- 세 번째 열: 명령어 이름(opcode)
- 네 번째 열: 명령어에 대한 인자(operand. 일부 문헌에선 argument라고도 함)
- 다섯 번째 열: 인자의 실제 값(괄호 안)
Python 가상 머신의 stack 기반 실행 모델
Python 가상 머신은 스택 기반으로 동작합니다. 대부분의 바이트코드 명령어는 이 스택을 조작하며 작업을 수행합니다:
- LOAD 계열 명령어
- LOAD_FAST, LOAD_CONST 등
- 값을 스택에 푸시(push).
- STORE 계열 명령어
- 스택에서 값을 팝(pop)하여
- 변수에 저장
- 연산 명령어
- BINARY_ADD 등
- 스택에서 값들을 pop하여 연산 후 결과를 다시 스택에 push.
예를 들어, a + b
연산이 실행될 때 스택의 변화는 다음과 같음:
LOAD_FAST 0 (a) # 스택: [a의 값]
LOAD_FAST 1 (b) # 스택: [a의 값, b의 값]
BINARY_ADD # 스택: [a+b의 결과]
스택 기반 모델은 JVM이나 .NET CLR과 같은 다른 가상 머신에서도 널리 사용되는 방식임.
주요 바이트코드 명령어
변수 관련 명령어
- LOAD_CONST:
- 상수 테이블에서 값을 가져와 스택에 Push.
- 인자는 상수 테이블의 index.
- STORE_FAST:
- 스택 최상위 값을 지역 변수에 저장.
- 인자는 지역 변수 테이블의 index.
- LOAD_FAST:
- 지역변수 배열에서 해당 index의 지역 변수의 값을 스택에 Push.
- "FAST"는 가장 빠른 변수 접근 방식을 의미.
- LOAD_GLOBAL:
- 전역 변수나 내장 함수를 스택에 push.
연산 및 함수 호출
- BINARY_ADD:
- 스택의 상위 두 값을 pop하여
- 더한 후 결과를 스택에 push.
- CALL:
- 함수를 호출.
- 인자는 호출에 사용된 인자 개수.
- RETURN_VALUE/RETURN_CONST:
- 스택 최상위 값(또는 지정된 상수)을 함수의 반환 값으로 사용.
제어 흐름
- RESUME: 함수 실행을 시작하거나 재개(Python 3.11+).
- POP_TOP: 스택 최상위 값을 제거.
dis 모듈의 활용
dis
모듈은 다음과 같은 상황에서 유용함:
- 코드 최적화: 코드가 어떻게 컴파일되는지 확인하여 성능 병목을 식별할 수 있음.
- 디버깅: 복잡한 버그를 추적할 때 코드의 실제 실행 흐름을 이해하는 데 도움이 됨.
- 학습: Python의 내부 작동 방식을 더 깊이 이해할 수 있음.
- 메타프로그래밍: 코드 생성이나 조작을 위한 도구를 개발할 때 유용함.
사용관련 예제
2025.03.11 - [CE] - [Py] bytecode 분석 - dis 모듈
[Py] bytecode 분석 - dis 모듈
(main) script 부분Python에서 "main script"는 프로그램 실행을 시작하는 주 진입점이 되는 Python 파일 또는 source code를 의미함. 0 0 RESUME 0 1 2 LOAD_CONST 0 () 4 MAKE_FUNCTION 0 6 STORE_NAME 0 (func)RESUME 0: 코드 실행 시
ds31x.tistory.com
'Python' 카테고리의 다른 글
[PyTorch] 생성 및 초기화, 기본 조작 (0) | 2025.03.13 |
---|---|
[Ex] PySide6 (0) | 2025.03.11 |
[DL] Tensor 다루기 - PyTorch 중심 (0) | 2025.03.07 |
[Py] How to Install Python on Windows from Python.org (0) | 2025.03.06 |
[PyTorch] torchvision.transform 사용법 (0) | 2025.01.12 |