Disassembling Python Bytecode: How the Virtual Machine Executes Code
August 8, 20265 min read
Python
Compiler
Bytecode
Internals
CPython compiles Python source code into bytecode before executing it on a stack-based virtual machine. Analyzing bytecode gives engineers deep insight into language mechanics and runtime performance.
The dis Module
Python’s built-in dis module lets us inspect the exact bytecode instructions generated by the compiler.
import dis
def compute_sum(numbers: list[int]) -> int:
total = 0
for num in numbers:
total += num
return total
print("--- Bytecode for compute_sum ---")
dis.dis(compute_sum)
Comparing List Comprehensions vs. Map/Filter
Let’s inspect why list comprehensions in Python are generally faster than for loops appending to a list:
import dis
def method_append(data: list[int]):
result = []
for item in data:
if item % 2 == 0:
result.append(item * 2)
return result
def method_comprehension(data: list[int]):
return [item * 2 for item in data if item % 2 == 0]
print("--- Append Method ---")
dis.dis(method_append)
print("\n--- Comprehension Method ---")
dis.dis(method_comprehension)
Key Observations
- List comprehensions utilize optimized
LIST_APPENDopcodes directly on the evaluation stack without performing global scope lookups for.append. - Modern CPython (3.11+) features Adaptive Bytecode Execution (PEP 659), which dynamically specializes opcodes at runtime based on type feedback.