Should I use
(apply + (filter prime? (range 1 20)))
or
(reduce + (filter prime? (range 1 20)))
Edit: This is the source for prime in clojure from optimizing toolkit.
(defn prime? [n]
(cond
(or (= n 2) (= n 3)) true
(or (divisible? n 2) (< n 2)) false
:else
(let [sqrt-n (Math/sqrt n)]
(loop [i 3]
(cond
(divisible? n i) false
(< sqrt-n i) true
:else (recur (+ i 2)))))))
If you are asking in terms of performance, the reduce
is better by a little:
(time (dotimes [_ 1e6] (apply + (filter even? (range 1 20)))))
"Elapsed time: 9059.251 msecs"
nil
(time (dotimes [_ 1e6] (reduce + (filter even? (range 1 20)))))
"Elapsed time: 8420.323 msecs"
nil
About 7% difference in this case, but YMMV depending on the machine.
You haven't provided your source for the prime?
function, so I have substituted even?
as the predicate. Keep in mind that your runtime may be dominated by prime?
, in which case the choice between reduce
and apply
matters even less.
If you are asking which is more "lispy" then I would say that the reduce
implementation is preferrable, as what you are doing is a reduce/fold in the functional programming sense.
I would think that reduce
would be preferable when it is available, because apply
uses the list as arguments to the function, but when you have a large number -- say, a million -- elements in the list, you will construct a function call with a million arguments! That might cause some problems with some implementations of Lisp.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With