Hi e,
Most of the time is taken up by printing, which is why you see the
same times. Here's an example that gives the results you would expect.
user> (def numbers (doall (take 500000 (repeatedly #(rand-int
3000)))))
#'user/numbers
user> (defn predicate [x] (< x 1500))
#'user/predicate
user> (dotimes [i 5]
(time (do (filt-rem predicate numbers) nil)))
"Elapsed time: 1028.112 msecs"
"Elapsed time: 715.832 msecs"
"Elapsed time: 923.726 msecs"
"Elapsed time: 631.364 msecs"
"Elapsed time: 934.084 msecs"
nil
user> (dotimes [i 5]
(time (let [pair (separate predicate numbers)]
(dorun (first pair))
(dorun (second pair)))))
"Elapsed time: 2694.912 msecs"
"Elapsed time: 2818.482 msecs"
"Elapsed time: 3087.375 msecs"
"Elapsed time: 2992.607 msecs"
"Elapsed time: 2959.005 msecs"
nil
-Stuart Sierra
On Jan 25, 10:02 am, e <[email protected]> wrote:
> The IRC channel folks helped me implement what we discovered was
> already called "separate" in contribs. My point was to do a partition
> that generated the two lists "(passes pred)" and "(fails pred)" in one
> pass without recursion.
>
> We ended up with:
>
> (defn filt-rem [pred coll]
> (loop [l1 () l2 () [f & r] coll]
> (if f
> (if (pred f)
> (recur (conj l1 f) l2 r)
> (recur l1 (conj l2 f) r))
> (list l1 l2))))
>
> -- the name reaming "filter and remove", I was thinking
>
> There's some branching there, so perhaps it's not the most efficient
> code.
>
> Here's what's in contrib, and as Tim showed me in the pquicksort
> discussion, that last bit could be replaced by "remove":
>
> (defn separate
> "Returns a vector:
> [ (filter f s), (filter (complement f) s) ]"
> [f s]
> [(filter f s) (filter (complement f) s)])
>
> Well, the recursive one that does two passes blows away filt-rem,
> according to 'time'. But if I just count in my head, they both take
> about as long.
>
> Yes, I started throwing doall all over the place. The other thing is
> we definately aren't talking about milliseconds. I.m not trying to
> measure how much time is spent in the reader or compiler or whatever.
> I care about the user waiting for the answer, and that's what I'm
> trying to time.
>
> Here's what I'm seeing, even though I don't believe it:
>
> (def l1 (doall (take 50000 (repeatedly #(rand-int 3000))))) ;;; I
> don't know if doall goes there, just shotgunning it at this point
>
> (time (filt-rem #(< % 1500) (doall l1))) ;;;; I've tried doall in
> various places with no help
> "Elapsed time: 63.158 msecs" <------ no way. It took like 12
> seconds
>
> (time (separate #(< % 1500) (doall l1))) ;;;;;; doall here
> actually did something even though already done above
> "Elapsed time: 12.701 msecs" <----------- no way. 12 seconds, I
> counted. Definitely longer than 12 msecs.
>
> Questions:
>
> 1) Is there anything wrong with filt-rem or anything to improve it?
> 2) why are the times reportedly so different when I can tell they
> return in about the same amount of time?
>
> Thanks.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---