PI Approximation: Why is my declarative version slower?

I approximate PI using the series:

PI Sereies

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.
+4
source share
1

, , . ,

(defn alt-sum [f n]
  (- (apply + (map f (range 1 (inc n) 2)))
     (apply + (map f (range 2 (inc n) 2)))))

(time (* 4 (alt-sum #(/ 1.0 (dec (+ % %))) 999999)))
; "Elapsed time: 195.244047 msecs"
;= 3.141593653590707

pi 2500 . pi pi-fn ( ) . ( 10 , alt-sum). pi-fn , pi. , 9 ? , , , .

scratch.core> (time (pi 999999))
"Elapsed time: 2682.86669 msecs"
3.1415936535907734
scratch.core> (time (pi-fn 999999))
"Elapsed time: 2082.071798 msecs"
3.1415936535907734
scratch.core> (time (pi-fn-juan 999999))
"Elapsed time: 1934.976217 msecs"
3.1415936535907734
scratch.core> (time (* 4 (alt-sum #(/ 1.0 (dec (+ % %))) 999999)))
"Elapsed time: 199.998438 msecs"
3.141593653590707
+3

Source: https://habr.com/ru/post/1537435/


All Articles