Holy Shmoly, GHC Haskell 6.8 smokes Python and Ruby away! And you can parallelise it for free
cgi.cse.unsw.edu.au
cgi.cse.unsw.edu.au
So the upside of a pure functional language is you don't have to explicitly memoize. To see the downside, try explaining monads to an undergrad.
Haskell is a cool enough language that it doesn't need misleading hype like this post.
And it obviously isn't memoizing. If the function were memoized, the timing would be much, much less than 0.48 seconds.
I tried this same Fibonacci function on my machine using GHC 6.8.1, and it's clearly O(1.62^N).
I withdraw my earlier dumb statement.
Dons is still arguably pulling a fast one, though. Even though the Haskell program looks like it should behave in more-or-less the same way as the other two, the semantics are actually quite different. Haskell defaults to lazy evaluation with memoization -- hence the "naive" recursion isn't really naive. That's where the orders of magnitude come from.
That said, Haskell is still a pretty fast language, on par with Java.
Here's a version that really is memoized:
import Control.Parallel
import Control.Monad
import Text.Printf
cutoff = 35
fibs = [ fib n | n <- [0..] ]
fib' :: Int -> Integer
fib' 0 = 0
fib' 1 = 1
fib' n = fibs !! (n-1) + fibs !! (n-2)
fib :: Int -> Integer
fib n | n < cutoff = fib' n
| otherwise = r `par` (l `seq` l + r)
where
l = fibs !! (n-1)
r = fibs !! (n-2)
main = forM_ [0..45] $ \i ->
printf "n=%d => %d\n" i (fib i)