Hi, On 16 Nov., 02:31, Ken Wesson <kwess...@gmail.com> wrote:
> Eh. I'd heard first and rest had replaced next. No? No. This was a misinformation. To elaborate a bit more on the differences pointed out by Sean: next returns nil if there are no more items in the sequence, which is nice to use in if and when statements to test for emptiness. However in order to be able to return nil the sequence has to be realised. Otherwise you can't know whether to return nil or not. So next is "non- lazy of order 1" so to say. To allow full laziness lazy-seq was introduced. It returns an object which doesn't know directly whether it's empty, but it knows how to find out, when you ask for it. When you know call empty? on the lazy-seq you realise the sequence and the seq call hidden in empty will return most likely a Cons, where first and rest are just field references, or nil of there are no elements in the sequence. But you throw this away. Then you call first on the lazy- seq. first itself calls seq and gets again the now cached Cons. Then you call rest, which calls seq, which returns the cached Cons. A lot of indirection going on. If you handle non-seqs like vectors or maps, you have to replace that with multiple creations of very short-lived objects. This is even more expensive. So you can see, that by capturing the return value of the seq call you can save quite a bit of indirection. Plus seq becomes the identity, which should be fast. I did some quick'n'dirty benchmarking and the improvement seems to be 12% for me. Not thaaaat much, but quite a bit for such trivial changes. user=> (bench (loop [s (take 10000 (range)) i 0] (if (empty? s) i (recur (rest s) (+ i (first s)))))) Evaluation count : 8100 Execution time mean : 7,393586 ms 95,0% CI: (7,391431 ms, 7,394906 ms) Execution time std-deviation : 3,062580 ms 95,0% CI: (3,043205 ms, 3,086849 ms) Found 2 outliers in 60 samples (3,3333 %) low-severe 2 (3,3333 %) Variance from outliers : 22,2178 % Variance is moderately inflated by outliers nil user=> (bench (loop [s (seq (take 10000 (range))) i 0] (if s (recur (next s) (+ i (first s))) i))) Evaluation count : 9840 Execution time mean : 6,502692 ms 95,0% CI: (6,499507 ms, 6,505352 ms) Execution time std-deviation : 3,708928 ms 95,0% CI: (3,687700 ms, 3,731890 ms) nil Hope that helps. Sincerely Meikel -- 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