I have found Clojure to be consistently faster than Python, so I thought it would be instructive to compare the Python code to the closest Clojure equivalent.
Here's the originally posted Python code: from itertools import repeat def convolve(ns, ms): y = [i for i in repeat(0, len(ns)+len(ms)-1)] for n in range(len(ns)): for m in range(len(ms)): y[n+m] = y[n+m] + ns[n]*ms[m] return y Now, if you want to write this functionally in Clojure, you've got two main obstacles in your way. First, you can't "bang a vector in place" -- you want to use Clojure's built-in persistent vectors. For the best speed, you can call transient at the beginning of the operations and persistent! at the end, but you still need to pass the vector around as an accumulator. This leads to the second obstacle -- because you're not "banging a vector in place" you can't really use for loops or doseq loops to conveniently iterate through the indices. You need to unroll these for loops into loop/recur constructs. It's a bit of a nuisance to do all this, but it's actually a fairly straightforward translation process. Here's what you get: (defn convolve [ns ms] (let [ns (vec ns), ms (vec ms), count-ns (count ns), count-ms (count ms)] (loop [n 0, y (transient (vec (repeat (dec (+ count-ns count-ms)) 0)))] (if (= n count-ns) (persistent! y) (recur (inc n) (loop [m 0, y y] (if (= m count-ms) y (let [n+m (+ n m)] (recur (inc m) (assoc! y n+m (+ (y n+m) (* (ns n) (ms m))))))))))))) By my measurements, this Clojure code runs (under java -server) twice as fast as the comparable Python code. Considering that Clojure's math is inherently slower than Python's, and Clojure is using more expensive persistent data structures, it's impressive that Clojure is faster. Clojure also offers the opportunity to go faster (with Java arrays), and even to deliver the results lazily if that's useful to you (but unsurprisingly, the laziness comes at a bit of a cost). Others have described those solutions, so I won't rehash those here. But there are two strikes against Clojure here: 1. This Clojure code is definitely harder to read than the Python equivalent. The transformation obfuscates what's going on. 2. Running the Python code under the psyco JIT compiler speeds the Python code up by a factor of 10, making it about 5 times faster than this Clojure transformation. So Python still gets the final word in speed here (comparing the exact same algorithm on their built-in data structures). -- 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