Fast Fibonacci recursion
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The naive recursive Fibonacci runs in O(2^n) time because it recomputes the same subproblems. There are several ways to make Fibonacci fast: memoization reduces it to O(n), bottom-up iteration also runs in O(n) with O(1) space, and matrix exponentiation achieves O(log n) time. The fastest practical approach for most use cases is memoization or iteration, while matrix exponentiation is useful for extremely large values of n.
Naive Recursion (O(2^n))
Each call branches into two recursive calls, creating an exponential call tree. fib(5) computes fib(3) twice and fib(2) three times.
Memoization (O(n) Time, O(n) Space)
@lru_cache stores previously computed results. Each fib(k) is calculated exactly once, reducing time from O(2^n) to O(n). A manual dictionary approach works the same way:
Bottom-Up Iteration (O(n) Time, O(1) Space)
This is the most practical approach for most applications. It uses constant space by only keeping the two most recent values.
Matrix Exponentiation (O(log n))
The Fibonacci recurrence can be expressed as a matrix multiplication:
By using fast matrix exponentiation (repeated squaring), this computes F(n) in O(log n) multiplications:
Without numpy, a pure Python implementation:
Fast Doubling (O(log n), No Matrix)
Fast doubling uses two identities to compute F(n) from F(n/2):
- F(2k) = F(k) * [2*F(k+1) - F(k)]
- F(2k+1) = F(k)^2 + F(k+1)^2
Fast doubling has the same O(log n) complexity as matrix exponentiation but avoids matrix overhead and is simpler to implement.
Performance Comparison
| Method | Time | Space | F(50) time | F(10000) feasible? |
| Naive recursion | O(2^n) | O(n) stack | Minutes | No |
| Memoization | O(n) | O(n) | Instant | Yes |
| Iteration | O(n) | O(1) | Instant | Yes |
| Matrix exponentiation | O(log n) | O(1) | Instant | Yes |
| Fast doubling | O(log n) | O(log n) stack | Instant | Yes |
Common Pitfalls
- Hitting Python's recursion limit with memoization: Python's default recursion limit is 1000. For
fib_memo(5000), you getRecursionError. Either increase the limit withsys.setrecursionlimit()or use the iterative approach for large n. - Integer overflow in typed languages: In Java or C++,
longoverflows around F(92). UseBigIntegerin Java orunsigned long longin C++ for larger values. Python handles arbitrary-precision integers natively. - Using mutable default arguments carelessly: The manual memoization pattern
def fib(n, cache={})uses a mutable default that persists across calls, which is the desired behavior here but can cause subtle bugs in other contexts. - Forgetting that matrix exponentiation has a large constant factor: For small n (under ~1000), the overhead of matrix multiplication makes O(log n) matrix exponentiation slower than simple O(n) iteration. Use matrix methods only when n is very large.
- Confusing fast doubling with divide-and-conquer without memoization: A naive divide-and-conquer that computes
fib(n//2)twice per call is still exponential. Fast doubling works because it computes both F(k) and F(k+1) in a single recursive call, halving the problem once per step.
Summary
- Naive recursion is O(2^n) — never use it for n > 30
- Memoization (
@lru_cache) or bottom-up iteration bring it to O(n) — best for most use cases - Matrix exponentiation and fast doubling achieve O(log n) — useful for very large n or competitive programming
- Bottom-up iteration with O(1) space is the most practical general-purpose solution
- Fast doubling is the simplest O(log n) approach, avoiding matrix multiplication overhead
Related reading

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.