Re: parallel iteration
On 24/03/2009 1:06, pmf wrote: On Mar 24, 12:01 am, Rowdy Rednoserowdy.redn...@gmx.net wrote: Hi group, say I have 2 sequences (def seq-a '(a1 a2 a3)) (def seq-b '(b1 b2 b3)) and want to iterate over them in parallel, like this (par-doseq [a seq-a b seq-b] (prn a b)) which should print a1 b1 a2 b2 a3 b3 A combination of the interleave and partition functions would probably do what you want: (partition 2 (interleave [:a :b :c] [:d :e :f])) (Wrap it in a doall to force your side effects.) Another one : (doseq [[a b] (map vector '(1 2 3) '(a b c))] (println a b)) (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(doseq [~(vec (map first ,bindings)) (map vector ~@(map second ,bindings))] ~...@body))) cara.nio.echo= (par-doseq [a '(1 2 3) b '(a b c)] (println a b)) 1 a 2 b 3 c nil Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
Thanks guys, these solutions look much better already. But do I always have to have these 2 steps * merge collection * split collection It feels a bit inefficient, I don't know if it actually is, though. On Mar 24, 8:05 pm, Phlex ph...@telenet.be wrote: On 24/03/2009 1:06, pmf wrote: On Mar 24, 12:01 am, Rowdy Rednoserowdy.redn...@gmx.net wrote: Hi group, say I have 2 sequences (def seq-a '(a1 a2 a3)) (def seq-b '(b1 b2 b3)) and want to iterate over them in parallel, like this (par-doseq [a seq-a b seq-b] (prn a b)) which should print a1 b1 a2 b2 a3 b3 A combination of the interleave and partition functions would probably do what you want: (partition 2 (interleave [:a :b :c] [:d :e :f])) (Wrap it in a doall to force your side effects.) Another one : (doseq [[a b] (map vector '(1 2 3) '(a b c))] (println a b)) (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(doseq [~(vec (map first ,bindings)) (map vector ~@(map second ,bindings))] ~...@body))) cara.nio.echo= (par-doseq [a '(1 2 3) b '(a b c)] (println a b)) 1 a 2 b 3 c nil Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
You could define a helper function, zip (as in Haskell) : (def zip (partial map list)) and then use as showed above: (doseq [[x y] (zip [:a :b] [1 2])] (println x: x , y: y)) 2009/3/24 Rowdy Rednose rowdy.redn...@gmx.net Thanks guys, these solutions look much better already. But do I always have to have these 2 steps * merge collection * split collection It feels a bit inefficient, I don't know if it actually is, though. On Mar 24, 8:05 pm, Phlex ph...@telenet.be wrote: On 24/03/2009 1:06, pmf wrote: On Mar 24, 12:01 am, Rowdy Rednoserowdy.redn...@gmx.net wrote: Hi group, say I have 2 sequences (def seq-a '(a1 a2 a3)) (def seq-b '(b1 b2 b3)) and want to iterate over them in parallel, like this (par-doseq [a seq-a b seq-b] (prn a b)) which should print a1 b1 a2 b2 a3 b3 A combination of the interleave and partition functions would probably do what you want: (partition 2 (interleave [:a :b :c] [:d :e :f])) (Wrap it in a doall to force your side effects.) Another one : (doseq [[a b] (map vector '(1 2 3) '(a b c))] (println a b)) (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(doseq [~(vec (map first ,bindings)) (map vector ~@(map second ,bindings))] ~...@body))) cara.nio.echo= (par-doseq [a '(1 2 3) b '(a b c)] (println a b)) 1 a 2 b 3 c nil Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
@Rowdy Take the time to do the interleave example by hand. You'll it does exactly what you want in one pass. On Mar 24, 10:10 am, Rowdy Rednose rowdy.redn...@gmx.net wrote: Thanks guys, these solutions look much better already. But do I always have to have these 2 steps * merge collection * split collection It feels a bit inefficient, I don't know if it actually is, though. On Mar 24, 8:05 pm, Phlex ph...@telenet.be wrote: On 24/03/2009 1:06, pmf wrote: On Mar 24, 12:01 am, Rowdy Rednoserowdy.redn...@gmx.net wrote: Hi group, say I have 2 sequences (def seq-a '(a1 a2 a3)) (def seq-b '(b1 b2 b3)) and want to iterate over them in parallel, like this (par-doseq [a seq-a b seq-b] (prn a b)) which should print a1 b1 a2 b2 a3 b3 A combination of the interleave and partition functions would probably do what you want: (partition 2 (interleave [:a :b :c] [:d :e :f])) (Wrap it in a doall to force your side effects.) Another one : (doseq [[a b] (map vector '(1 2 3) '(a b c))] (println a b)) (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(doseq [~(vec (map first ,bindings)) (map vector ~@(map second ,bindings))] ~...@body))) cara.nio.echo= (par-doseq [a '(1 2 3) b '(a b c)] (println a b)) 1 a 2 b 3 c nil Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
On 24/03/2009 15:10, Rowdy Rednose wrote: Thanks guys, these solutions look much better already. But do I always have to have these 2 steps * merge collection * split collection It feels a bit inefficient, I don't know if it actually is, though. Allright let's see what we can do : make a macro out of this : (loop [a '(1 2 3) b '(a b c d)] (when (and (seq a) (seq b)) (println (first a) (first b)) (recur (rest a) (rest b Might be easier to make a function first (defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? identity (map seq rests)) (apply fn (map first rests)) (recur (map rest rests) cara= (par-doseq-fn #(println %1 %2) '(1 2 3) '(a b c)) 1 a 2 b 3 c (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(par-doseq-fn (fn ~(vec (map first bindings)) ~...@body) ~@(map second bindings cara= (par-doseq [a '(0 1 2) b '(a b c)] (println a b)) 0 a 1 b 2 c nil Now you get to run the micro-benchmarks ! Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
(defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? identity (map seq rests)) (apply fn (map first rests)) (recur (map rest rests) It should of course be like this : (defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? seq rests) (apply fn (map first rests)) (recur (map rest rests) Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
(defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? identity (map seq rests)) (apply fn (map first rests)) (recur (map rest rests) It should of course be like this : (defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? seq rests) (apply fn (map first rests)) (recur (map rest rests which amounts to (def par-doseq-fn (comp dorun map)) Though there is some consing going on as a result of the map... Ok that's it, enough of me flooding the mailing list =P Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
Thanks all, microbenchmarking shows that a simple (time (doseq [[a b] (map vector list-a list-b)])) is ~50% faster on my system than (def par-doseq-fn (comp dorun map)) (defmacro par-doseq [bindings body] (let [bindings (partition 2 bindings)] `(par-doseq-fn (fn ~(vec (map first bindings)) ~...@body) ~@(map second bindings (time (par-doseq [a list-a b list-b] (+ a b))) I used these lists: (def list-a (repeat 40 1234)) (def list-b (repeat 40 2345)) On Mar 25, 1:22 am, Phlex ph...@telenet.be wrote: (defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? identity (map seq rests)) (apply fn (map first rests)) (recur (map rest rests) It should of course be like this : (defn par-doseq-fn [fn seqs] (loop [rests seqs] (when (every? seq rests) (apply fn (map first rests)) (recur (map rest rests which amounts to (def par-doseq-fn (comp dorun map)) Though there is some consing going on as a result of the map... Ok that's it, enough of me flooding the mailing list =P Sacha --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Re: parallel iteration
On Mar 24, 12:01 am, Rowdy Rednose rowdy.redn...@gmx.net wrote: Hi group, say I have 2 sequences (def seq-a '(a1 a2 a3)) (def seq-b '(b1 b2 b3)) and want to iterate over them in parallel, like this (par-doseq [a seq-a b seq-b] (prn a b)) which should print a1 b1 a2 b2 a3 b3 A combination of the interleave and partition functions would probably do what you want: (partition 2 (interleave [:a :b :c] [:d :e :f])) (Wrap it in a doall to force your side effects.) --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---