On Sat, Feb 02, 2013 at 06:28:09PM -0800, Alexandros Bantis wrote:

> Hello all. I'm working through the Project Euler problems in Java,
> Scala, & Clojure (trying to learn all three?!?). I notice that for one
> particular problem, I use--more or less--a similar algorithm for all
> three, but the clojure code runs about 20-30 times slower than the
> java/scala versions. Does anyone have any idea why this might be? It
> strikes me that it might have something to do with every? but I don't
> know because I'm a newbie with Clojure.

Daniel Solano Gómez gave a very interesting talk last summer about
numerical performance in Clojure:

http://www.infoq.com/presentations/Crunching-Numbers-Clojure

While there are many technical tips about boosting math performance,
Daniel's overarching point is that the best speed boost is the _right
algorithm_. For instance, this solution to the problem runs in ~2ms:

```

(def primes
  "This should be a lazy-seq of primes generated by a bit-sieve, but for
   this example the largest prime we need is 3!"
  [2 3])

(defn prime-factors [n]
  (loop [n n fs []]
    (if-let [p (first (for [p primes
                            :while (<= p (int (Math/sqrt n)))
                            :when (zero? (rem n p))]
                        p))]
      (recur (/ n p) (conj fs p))
      (conj fs n))))

(defn lcm
  "The lowest common multiple of a set of numbers is the product of the
   distinct prime factors in the set each raised to the power of the
   greatest occurence in a single number."
  [& xs]
  (let [fqs (map #(frequencies (prime-factors %)) xs)]
    (apply * (map (fn [p] (Math/pow p (apply max (map #(get % p 0) fqs))))
                  (set (mapcat keys fqs))))))

(time
  (long (apply lcm (range 2 21))))

"Elapsed time: 2.010032 msecs"
232792560

```

I know you are explicitly asking for language implementation
differences, but I believe you would be better served in this instance
by studying more elegant algorithms.

The fastest code in any language is the code that does not execute;
designing with this in mind is especially important in Clojure, where
the functional abstractions are beautiful, but somewhat costly.

    guns

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to