Let's say I define the sequence of all natural numbers in the following way:
(def naturals (iterate inc 0))
I also define a function mapping the naturals to nil that takes a while to compute like so:
(defn hard-comp [_] (Thread/sleep 500))
Note the computation time to evaulate the following s-expressions as measured by clojure.core/time
.
(dorun (map hard-comp (range 30))) ;
15010.367496 msecs
(dorun (pmap hard-comp (range 30))) ;
537.044554 msecs
(dorun (map hard-comp (doall (take 30 naturals))))) ;
15009.488499 msecs
(dorun (pmap hard-comp (doall (take 30 naturals)))) ;
3004.499013 msecs
(doall (take 30 naturals)) ;
0.385724 msecs
(range 30)
; 0.159374 msecs
pmap
is ~6 times faster when called with an explicit range than with a section of the naturals.
Since (= (range 30) (take 30 naturals))
returns true and both objects are of type clojure.lang.LazySeq
, and clojure evaulates all the arguments to a function before calling the function, how can the above timing details be explained?