Let's look at four different functions that compute the nth fibonacci number, using pseudocode instead of restricting the program to a single language. The first follows the standard recursive definition:
function fib(n) # exponential
if n <= 2 return 1
return fib(n-1) + fib(n-2)
This function requires exponential time, O(2n), because it recomputes previously-computed fibonacci numbers at each step. The second function requires linear time, O(n), by working from 1 to n instead of n to 1 and keeping track of the two previous fibonacci numbers:
function fib(n) # linear
if n <= 2 return 1
prev2 = prev1 = 1
k := 3
while k <= n
fib := prev2 + prev1
prev2 := prev1
prev1 := fib
return fib
That's the same algorithm your program uses, though yours disguises what's going on by operating recursively and passing one of the parameters by a pointer to a variable in an outer scope.
Dijkstra described an algorithm for computing the n fibonacci number in logarithmic time, O(log n), using matrices and the exponentiation by squaring algorithm. I won't give the full explanation here; Dijkstra does it better than I could (though you should beware his convention that F0 = 1 instead of F0 = 0 as we have been doing it). Here's the algorithm:
function fib(n) # logarithmic
if n <= 2 return 1
n2 := n // 2 # integer division
if n % 2 == 1 return square(fib(n2+1)) + square(fib(n2))
return fib(n2) * (2*fib(n2-1) + fib(n2))
The fourth algorithm operates in constant time, O(1), provided you have floating-point numbers with sufficient precision, using the mathematical definition of the fibonacci numbers:
function fib(n) # constant
sqrt5 := sqrt(5)
p := (1 + sqrt5) / 2
q := 1 / p
return floor((p**n + q**n) / sqrt5 + 0.5)
For most languages this last algorithm isn't very useful, because for fibonacci numbers of any size you need some kind of unlimited-precision decimal arithmetic library, and although it's constant time it will probably take longer in practice than the simple logarithmic-time algorithm operating on unlimited-precision integers, at least until n is very large.