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 <evier...@gmail.com> 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 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to