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_fastandfib_super_fastexecute 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
iis unnecessary and you can decreaseninstead until it's 0.By the way, you didn't set default values for
currandprev, 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
returns asifis an expression...