I approximate PI using the series:

The function for the series is as follows:
(defn- pi-series [k]
(/ (if (even? (inc k)) 1 -1)
(dec (* 2 k))))
And then my series generator looks like *:
(defn pi [n]
(* 4
(loop [k 1
acc 0]
(if (= k (inc n))
acc
(recur (inc k)
(+ acc (double (pi-series k))))))))
Running piwith a value 999,999causes the following:
(time (pi 999999))
;;=> "Elapsed time: 497.686 msecs"
;;=> 3.1415936535907734
It looks great, but I understand that it pican be written more declarative. Here is what I ended up with:
(defn pi-fn [n]
(* 4 (reduce +
(map #(double (pi-series %))
(range 1 (inc n))))))
This led to the following:
(time (pi-fn 999999))
;;=> "Elapsed time: 4431.626 msecs"
;;=> 3.1415936535907734
NOTE. The declarative version took about 4 seconds. Why?
Why is the declarative version much slower? How can I update the declarative version to make it as fast as the strong version?
- I am making the pi-series result double, because using clojure relationship types was much slower.
source
share