Hi, all.

A while ago I came across this SO question: Best way to lazily collapse 
multiple contiguous items of a sequence into a single 
item<http://stackoverflow.com/questions/6728567/best-way-to-lazily-collapse-multiple-contiguous-items-of-a-sequence-into-a-single>

Long story short, I posted an answer that was concise and (imo) readable, 
but that performed very poorly.  The asker pressed the perf aspect a bit and 
I decided to look into in.  Below is my initial answer and a second version 
that is 3x faster.  I'm trying to understand why the first answer is slow.

Code:

(defn collapse-slow [col pred rep]
  (let [f (fn [[x & more :as xs]] (if (pred x) [rep] xs))]
    (mapcat f (partition-by #(if (pred %) true) col))))

; 3x faster than collapse-slow
(defn collapse [xs pred rep]
  (when-let [x (first xs)]
    (lazy-seq 
      (if (pred x)
        (cons rep (collapse (drop-while pred (rest xs)) pred rep))
        (cons x (collapse (rest xs) pred rep))))))

; test
(def is-wsp? #{\space \tab \newline \return})
(def test-str "\t    a\r          s\td  \t \r \n         f \r\n")

(println "slow:")
(time (dotimes [_ 1e6] (dorun (collapse-slow test-str is-wsp? \space))))
; "Elapsed time: 13484.177938 msecs"

(println "faster:")
(time (dotimes [_ 1e6] (dorun (collapse test-str is-wsp? \space))))
; "Elapsed time: 3662.257347 msecs"

Thanks,


Mark.

-- 
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

Reply via email to