Played a little with lazy-seq vs loop recur today, and got a suprise that lazy-seq is not as slow as I would have thought. Most likely the usecases are very different so by no means is this interchangably for most applications, but I assumed that a lazy-seq carries a lot of overhead. Don’t know why I thought that so, but playing around with it and timing the output I realized it seems to be a wrong assumption. By no means this is a real benchmark but it makes me read up more for sure.
(defn fib "Return the Nth fibonacci number." [n] (loop [i n p 0 pp 1] (if (zero? i) p (recur (dec i) (+ pp p) p)))) (defn lazy-fib "Return the fibonacci sequence as a lazy sequence." ([] (lazy-fib 0 1)) ([p pp] (lazy-seq (cons p (lazy-fib pp (+ p pp)))))) (let [n 60] (println "Nth number:") (time (fib n)) (println "Non lazy:") (time (last (take n (map fib (range))))) (println "Lazy:") (time (last (take n (lazy-fib))))) ;; Nth number: ;; "Elapsed time: 0.022058 msecs" ;; Non lazy: ;; "Elapsed time: 0.133195 msecs" ;; Lazy: ;; "Elapsed time: 0.026575 msecs"
Seems like lazy-seq is at least same order of magnitude to just calculating N for fibonacci here, and creating a non lazy seq seems much slower. No optimization what so ever here, and also being pretty brute force about the recursion in the lazy-fib.