Tassilo Horn <tass...@member.fsf.org> writes:

>>> You should probably inline comp for your purposes. Note the reverse
>>> call there.
>>>
>>> https://github.com/clojure/clojure/blob/d0c380d9809fd242bec688c7134e900f0bbedcac/src/clj/clojure/core.clj#L2267
>>
>> Oh, that's a pity.  I'd much vote for a left-to-right version
>> complementing the current right-to-left `comp`.
>
> I created a JIRA issue and added a patch:
>
>   http://dev.clojure.org/jira/browse/CLJ-1010

Now that's strange.  If I adapt Yoshinori's code to use a list again and
the left-to-right `comp*` instead of the reversing `comp`, I expected to
get a reasonable benefit.  I.e., that's the new code
(https://gist.github.com/2908767).

--8<---------------cut here---------------start------------->8---
(defn r-reduce [init updt pred retn f coll]
  (loop [stat init [h & r :as curr] coll acc (list identity)]
    (if (or (pred stat) (nil? r))
      ;; comp* is left-to-right, so it doesn't reverse
      ((apply comp* acc) (retn curr))
      (recur (updt stat) r (cons (partial f h) acc)))))

(defn reduce-right [f coll]
  (r-reduce coll next nil? first f coll))
--8<---------------cut here---------------end--------------->8---

and that's the old version:

--8<---------------cut here---------------start------------->8---
(defn r-reduce-old [init updt pred retn f coll]
  (loop [stat init [h & r :as curr] coll acc (vector identity)]
    (if (or (pred stat) (nil? r))
      ;; Will reverse acc
      ((apply comp acc) (retn curr))
      (recur (updt stat) r (conj acc (partial f h))))))

(defn reduce-right-old [f coll]
  (r-reduce-old coll next nil? first f coll))
--8<---------------cut here---------------end--------------->8---

This seems to prove that `comp*` is much faster than `comp` if there are
many functions:

--8<---------------cut here---------------start------------->8---
user> (time (apply comp* (take 2000000 (repeat identity))))
"Elapsed time: 0.078991 msecs"
#<core$comp_STAR_$fn__4071 clojure.core$comp_STAR_$fn__4071@74cee5ed>
user> (time (apply comp (take 2000000 (repeat identity))))
"Elapsed time: 1515.573253 msecs"
#<core$comp_STAR_$fn__4071 clojure.core$comp_STAR_$fn__4071@4cb8cd94>
--8<---------------cut here---------------end--------------->8---

But strangely, this 1.5 second benefit is completely lost somewhere:

--8<---------------cut here---------------start------------->8---
user> (time (reduce-right-old - (range 2000000)))
"Elapsed time: 3992.088322 msecs"
-1000000
user> (time (reduce-right - (range 2000000)))
"Elapsed time: 4125.689783 msecs"
-1000000
--8<---------------cut here---------------end--------------->8---

Can someone enlighten me what's happening?

Thanks,
Tassilo

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