Took a shot at implementing PI in Clojure using a reasonably fast algorithm. So why is it so slow ? Is BigDecimal just that bad ? Would fixed point arithmetic be better using BigInteger ? (MacBook Pro - Intel Core 2 Duo 2.26 GHz - 4GB RAM)
(set! *warn-on-reflection* true) (import 'java.lang.Math) (import 'java.math.MathContext) (import 'java.math.RoundingMode) (import 'java.math.BigInteger) (import 'java.math.BigDecimal) (defn sb-pi [digits] "Calculates PI digits using the Salamin-Brent algorithm and Java's BigDecimal class." (let [mcdigits (new MathContext (+ 10 digits)) ; add 10 guard digits zero (new BigDecimal 0) one (new BigDecimal 1) two (new BigDecimal 2) four (new BigDecimal 4)] (defn big-sqrt[#^BigDecimal num digits] "Calculates square root using Newton's method." (defn big-sqrt-int [#^BigDecimal num #^BigDecimal x0 #^BigDecimal x1 digits] (if (not (. x0 equals x1)) (big-sqrt-int num x1 (. (. x1 add (. num divide x1 digits RoundingMode/ HALF_DOWN)) divide two digits RoundingMode/HALF_DOWN) digits) x1)) (big-sqrt-int num zero (. BigDecimal valueOf (Math/sqrt (. num doubleValue))) (+ 1 digits))) (defn sb-pi-int [#^BigDecimal a #^BigDecimal b #^BigDecimal x #^BigDecimal p n] (let [#^BigDecimal a1 (. (. a add b) divide two mcdigits) #^BigDecimal b1 (big-sqrt (. a multiply b mcdigits) digits) #^BigDecimal x1 (. x subtract (. p multiply (. (. a subtract a1) multiply (. a subtract a1) mcdigits) mcdigits)) #^BigDecimal p1 (. two multiply p mcdigits)] (if (> n digits) (. (. (. (. a1 add b1) multiply (. a1 add b1) mcdigits) divide (. four multiply x1) mcdigits) setScale digits RoundingMode/HALF_UP) (recur a1 b1 x1 p1 (* 2 n))))) (let [#^BigDecimal sa one #^BigDecimal sb (. one divide (big-sqrt two digits) mcdigits) #^BigDecimal sx (. one divide four) #^BigDecimal sp one] (sb-pi-int sa sb sx sp 1) ))) (time (println (sb-pi 1))) ;; 4.058 ms (time (println (sb-pi 10))) ;; 6.611 ms (time (println (sb-pi 100))) ;; 21.615 ms (time (println (sb-pi 1000))) ;; 211.314 ms (time (println (sb-pi 10000))) ;; 22090.236 ms --~--~---------~--~----~------------~-------~--~----~ 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 Note that posts from new members are moderated - please be patient with your first post. 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 -~----------~----~----~----~------~----~------~--~---