I watched One second to compute the largest Fibonacci number I can, I like comparing approaches and wanted to learn/ practice my design patterns for modern C++. Thought it would be a fun project to recreate. As usual, this is a toy-project aimed at being learning-friendly, demonstrating real-world C++ design patterns — dynamic extensibility, static initialization, and runtime polymorphism — all applied in a self-contained, enjoyable thing.
┌──────────────────────────────┐
│main.cpp │
│ - Program entry point │
│ - Lists available solvers │
│ - Benchmarks and runs them │
└────────────┬─────────────────┘
│
┌────────────▼─────────────────┐
│GenericSolverFactory │
│ - Manages all solver types │
│ - Unified interface for main │
└────────────┬─────────────────┘
│
┌────────────▼──────────────────────────────────────┐
│SolverFactory |
│ - Per-type factory |
│ - Knows how to construct solvers of IFibSolver │
│ - Registered via static or explicit code │
└────────────┬──────────────────────────────────────┘
│
┌────────────▼─────────────────────────┐
│IFibSolver Interface │
│ - Abstract base class │
│ - Each solver implements compute() │
└──────────────────────────────────────┘
- Naive (recursive)
- Naive (recursive memoized)
- Iterative (big int)
- Boost's
cpp_int
- Boost's
- Matrix Exponentiation
- SIMD-ed with ARM NEON
- Matrix Fast Doubling
I haven't handled data-types particularly well... I noticed in the NEON implementation, expected values diverge after F(92), it should just be a representation/ printing issue.
Generic factory pattern for creating different solver instances. Tried to minimize duplicative code, ended up duplicating registration.
Wouldn't bother. But, more solvers and approaches would be great to see :).