On Tue, Aug 4, 2009 at 10:13 PM, John Harrop<jharrop...@gmail.com> wrote:
> On Tue, Aug 4, 2009 at 5:50 PM, Rich Hickey <richhic...@gmail.com> wrote:
>>
>> On Aug 4, 4:31 pm, John Harrop <jharrop...@gmail.com> wrote:
>> > What about things like:
>> >
>> > (persistent!
>> >   (reduce
>> >     (fn [x [i v]] (assoc! x i v))
>> >     (transient (vec (repeat 0 (reduce max (map first
>> > coll-of-index-val-pairs)))))
>> >     coll-of-index-val-pairs))
>> >
>>
>> Yes, that's completely fine intended usage, as the return value of the
>> reducing fn becomes an argument to the next call.
>>
>> > which is just the transientification of
>> >
>>
>> Nice word - transientification.
>
> Thanks.
> Of course, this makes me think of ways to possibly speed up other
> operations. For example:
> (defn vmap* [fun vect]
>   (let [c (count vect)]
>     (loop [out (transient []) i 0]
>       (if (= i c)
>         out
>         (recur (conj! out (fun (nth vect i))) (inc i))))))
> (defn vmap [fun vect]
>   (persistent! (vmap* fun vect)))

> Vector in, vector out, conj'd up using a transient.

Mapping into vectors and similar ops are coming, although nothing like
vmap* would ever be exposed.

> And, of course:
> (defn vpmap [fun vect]
>   (loop [out (vmap* #(future (fun %)) vect) i (dec (count vect))]
>     (let [o2 (assoc! out i @(nth out i))]
>       (if (zero? i)
>         (persistent! o2)
>         (recur o2 (dec i)))))
> Note that this last manipulates a transient vector in a single thread,
> though other threads (from the agent pool) calculate a bunch of futures that
> are stored in it. The transient vector of futures is generated using the
> vmap* from above, and then the futures are replaced with their values
> in-place by the loop in vpmap, before this persistentizes and returns that
> vector. The future-dereferencing loop works backwards from the end of the
> vector in case zero? is a quicker test than a general equality test. This is
> likely on hardware that implements an equality test as a subtraction
> followed by a zero test, because it eliminates the subtraction. On the other
> hand, hardware with a 1-cycle equality test of 32-bit ints is plausible, as
> is hardware that optimizes forward traversal of vectors, so I can't vouch
> for that being an optimization. The first loop has to go forward to conj up
> the output vector without reversing it, though.
>

There is already a very nice pvmap in the par branch that uses
ForkJoin. I strongly recommend against trying to write parallel ops
with transients - that's not what they are for.

What's nice about pvmap is that, just like transients, it also takes,
manipulates, and returns ordinary Clojure vectors (unlike the old
parallel lib which copied into and out of ForkJoin's ParallelArrays).
The goal is to make using the normal data structures as powerful as
possible, and not needing to switch to something else for performance.

Rich

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