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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en