My first approach (the naive one) is very similar to @rapidnerd
's (George Marr's) solution in R and @andreanidouglas
' (Douglas R Andreani's) solution in Python:
I realized that this solution quickly exceeded in execution time for n > 40, so I optimized it using a mathematical theorem:
Given that n and p are integers, and that n = 2p + 1, i. e. n is odd, the n-th fibonacci number is then
fib(n) = fib(p + (p+1)) = fib(p)² + fib(p+1)²
This means, we can break down numbers with odd indices into to numbers with about the half of the index – and do this again and again and again. This dramatically reduces execution time:
I did this some time ago in Rust.
My first approach (the naive one) is very similar to @rapidnerd 's (George Marr's) solution in R and @andreanidouglas ' (Douglas R Andreani's) solution in Python:
I realized that this solution quickly exceeded in execution time for n > 40, so I optimized it using a mathematical theorem:
This means, we can break down numbers with odd indices into to numbers with about the half of the index – and do this again and again and again. This dramatically reduces execution time:
Inspired by @avalander 's answer, I also added this even faster algorithm:
fib_fast
andfib_super_fast
execute within microseconds even for higher indices. However, indices of 94 and higher cause a crash:Some performance measurements:
Nice!
Since writing my implementation I've remembered that the parameter
i
is unnecessary and you can decreasen
instead until it's 0.By the way, you didn't set default values for
curr
andprev
, how does that work, do you need to call it withfib_super_fast(n, 1, 0)
?Yes, I do. But I have to use fib_super_fast(n, 1, 1, 0) as my other implementations also begin with 1. The code for calling the fibonacci methods is:
Just for a nice style, you could factor out the
return
s asif
is an expression...