You think calling a function is cheap. It isn’t.
Every function call has a cost.
Today, you understand what actually happens when Python executes functions.
Today’s Goal
By the end of today, you will:
- Understand how function calls work internally
- Learn what a call stack is
- Visualize execution flow
- Understand performance impact of function calls
The Illusion
def add(a, b):
return a + b
add(2, 3)
You think:
Python just jumps into the function
Reality:
Python creates a new execution frame and pushes it to the stack
What Is a Call Stack?
Top → [Frame: add]
[Frame: main]
Bottom
A stack of execution frames.
What Happens During Function Call
When you call a function:
- Create a new frame
- Store local variables
- Push frame to stack
- Execute function
- Pop frame when done
Example
def f1():
f2()
def f2():
f3()
def f3():
print("done")
f1()
Stack Visualization
[ f3 ]
[ f2 ]
[ f1 ]
[ main ]
Then unwinds after execution.
Key Insight
Function calls are NOT free.
Each call involves:
- frame creation
- memory allocation
- stack operations
Recursion and Stack Growth
def recurse(n):
if n == 0:
return
recurse(n-1)
Each recursive call adds a frame.
Stack Overflow Risk
Too many calls:
RecursionError: maximum recursion depth exceeded
Python Recursion Limit
import sys
print(sys.getrecursionlimit())
Default ~1000
Why Limit Exists
To prevent:
- memory exhaustion
- crash due to deep recursion
Function Call Overhead
Compare:
# direct
x = 10 + 5
# function
add(10, 5)
Function call is slower due to overhead.
Performance Insight
In tight loops:
- avoid unnecessary function calls
- inline simple logic if needed
Local vs Global Lookup
x = 10
def f():
return x
Python searches:
- local scope
- global scope
- builtins
Cost of Lookup
Local lookup is fastest. Global is slower.
Optimization Trick
def f(x=x):
return x
Caches global into local scope.
Why This Matters
Function behavior impacts:
- performance
- memory usage
- recursion safety
Real Example
def square(x):
return x * x
for i in range(1_000_000):
square(i)
Repeated function calls add overhead.
Your Task
- trace a function call manually
- draw the call stack
- compare recursion vs loop performance
Common Mistakes
- overusing recursion
- ignoring call overhead
- deep nesting of function calls
Think Deeper
- What happens in memory during function call?
- Why are recursive calls risky?
- When should you avoid function calls?
Subtle Insight (CRITICAL)
Python execution is stack-driven.
Understanding the stack = understanding execution.
Tomorrow
Modules & Imports — how Python loads and links code
Rule
- Functions improve structure, not always performance
- Be aware of call cost
See you in Day 6.