Just out of curiosity - did you by any chance "warm up" the JVM to
make sure that the fib function was JIT'd before you did this
benchmark?

On Feb 23, 5:46 pm, Raffael Cavallaro <raffaelcavall...@gmail.com>
wrote:
> On Feb 23, 2:51 pm, "Stephen C. Gilardi" <squee...@mac.com> wrote:
>
> > The fibs implementation in clojure.contrib.lazy-seqs is not a function  
> > that returns fib(n) given n.
> > I think defining a fib(n) function somewhere in contrib or core that  
> > operates as efficiently as we can manage would be a good idea.
>
> There was a thread on comp.lang.lisp a while ago where a number of
> people went back and forth trying to come up withe the fastest fib(n)
> algorithm (again, *not* returning a sequence, but just the nth fib
> given n). Here is the winner of that informal competition translated
> to clojure:
>
> (defn fib
>   ([n]
>      (fib n 1))
>   ([n b]
>      (if (zero? b)                      ;calculate lucas numbers
>        (cond
>         (zero? n) 2
>         (= n 1) 1
>         :otherwise
>         (if (even? n)
>           (let [ k (/ n 2)
>                  l (fib k 0)]
>             (+ (* l l) (if (even? k) -2 2)))
>           (let [ k (- n 1)
>                  l (fib k 0)
>                  f (fib k 1)]
>             (/ (+ (* 5 f) l) 2))))
>        (cond                            ;calculate fibonacci numbers
>         (zero? n) 0
>         (= n 1) 1
>         :otherwise
>         (if (even? n)
>           (let [ k (/ n 2)
>                  l (fib k 0)
>                  f (fib k 1)]
>             (* f l))
>           (let [ k (- n 1)
>                  l (fib k 0)
>                  f (fib k 1)]
>             (/ (+ f l) 2)))))))
>
> btw, the relatively naive algorithm:
>
> (defn fib-naive [n]
>   (first (nth (iterate (fn [[a b]] [b (+ a b)]) [0 1]) n)))
>
> takes over 85 seconds, or more than 40 times as long as the lucas
> number based algorithm at top to compute the one millionth fibonacci
> number. The simple loop version:
>
> (defn fib-naive2 [n]
>   (loop [a 0 b 1 counter 0]
>     (if (= counter n) a
>         (recur b (+ a b) (inc counter)))))
>
> fares exactly the same as one might expect.
>
> for comparison, here are some timings under different lisps on the
> same machine. All timings are after several runs to warm up caches
> and, in the case of clojure, hotspot optimizations.
>
> Time to calculate the one millionth fibonacci number using the lucas
> number based algorithm at top:
>
> clojure: 2 seconds
> ccl: 0.5 seconds
> lispworks: 1.7 seconds
> mzscheme: 0.15 seconds
> sbcl: 0.8 seconds
> larceny: 13 seconds
> ecl: 0.04 seconds
>
> as you can see, clojure is competitive with other lisps/schemes,
> faster than some, slower than others. this is really just a benchmark
> of the bignum package used by the lisp implementation. I think ecl
> uses GMP which is quite fast.
>
> btw, I tried adding type annotations to the clojure version but it
> didn't seem to make much difference.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to