Strangely, I'm not seeing my own emails turn up in this list...
Anyways, after re-reading what I sent, it only partially applies :-)
The obvious (deliberate, of course) mistake with my vector-of was that I
didn't return the vector that I'd built up! So set-flags was, of course,
rather fast in dealing with nil. Oops. So the (kind of proper)
implementation would be:
(defn vector-of [n value]
(loop [v []
c 0]
(if (< c n)
(recur (assoc v c value) (inc c))
v)))
The only thing that I can see that would speed up set-flags would be to
not take the length of the vector on every iteration: I suspect that may
involve a traversal of the vector every time it's called.
Cheers,
Danny.
On 19/10/2009 13:37, Stuart Campbell wrote:
> 2009/10/19 Danny Woods <[email protected]
> <mailto:[email protected]>>
>
>
> harto wrote:
> > Hello,
> >
> > I've just started learning Clojure, so I'm trying to figure out the
> > correct way of doing things. I've been trying to create and
> 'modify' a
> > large vector for an online programming exercise, but I'm running
> into
> > some performance issues.
> >
> > Any general tips would be appreciated!
> >
>
> Well, I'm a beginner too, but I'll take a stab at answering your
> questions.
>
> > Firstly, I'm creating a vector of booleans like this:
> >
> > (defn vector-of [n value]
> > (vec (for [_ (range n)] value)))
> >
> > It takes quite a long time for large values of n, though:
> >
> > user=> (time (dorun (vector-of 1e7 true)))
> > "Elapsed time: 6734.509528 msecs"
> >
> I suspect you're being bitten by the repeated creation of the
> underlying
> data structures. 'range' is going to create a lazy sequence, from
> which
> 'for' is going to create its own, lazy structure, which 'vec' then
> iterates over to create its own. Just running '(time (dorun (range
> 1e7)))' shows that it's taking up a non-trivial amount of time just on
> its own.
>
>
> Ah, OK. I didn't understand the implications of using those lazy
> sequences. I think I need to do some more reading on lazy data structures.
>
> Thanks for your input!
>
>
> This modified version does the same thing a little more quickly:
>
> (defn vector-of [n value]
> (loop [v []
> c 0]
> (if (< c n) (recur (assoc v c value) (inc c)))))
>
> user> (time (dorun (vector-of 1e7 true)))
> "Elapsed time: 1000.409039 msecs"
>
>
> > Secondly, I'm iterating across one of these large vectors using
> > something like the following (contrived) function:
> >
> > (defn set-flags [v]
> > (loop [i 0
> > v v]
> > (if (< i (count v))
> > (recur (inc i) (assoc v i false))
> > v)))
> >
> > user=> (let [v (vector-of 1e7 true)] (time (dorun (set-flags v))))
> > "Elapsed time: 15563.916114 msecs"
> >
> > Am I missing anything obvious here? That seems like a really
> long time
> > to me.
> >
> With the modified vector-of, above, this problem seems to go away
> for me:
>
> user> (time (dorun (set-flags (vector-of 1e7 true))))
> "Elapsed time: 1009.362723 msecs"
>
> Cheers,
> Danny.
>
>
>
> >
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---