On Nov 10, 2010, at 9:05 PM, Sean Corfield wrote: > On Wed, Nov 10, 2010 at 11:37 AM, Gary Poster <gary.pos...@gmail.com> wrote: >> In my opinion, its promise is that it reverses anything that supports the >> minimal seq interface. Its implementation can be pluggable via protocols > > Hmm, don't protocols have some overhead? Switching an implementation > from a direct, possibly inlined, function to one that uses protocols > is going to slow it down, surely?
The answer, as I expected, is "a small bit." I didn't get around to giving criterium (https://github.com/hugoduncan/criterium) a whirl for more careful statistics, but after a first run (JIT optimization doing its thing, I assume), these are some mins after a few runs, and representative. rseq is rseq, seq-reverse is a protocol-based reverse function copying the implementation of the built-ins, and s is a vector (vec (range 1000)). 1:49 user=> (time (dotimes [_ 10000] (rseq s))) "Elapsed time: 1.761 msecs" nil 1:50 user=> (time (dotimes [_ 10000] (seq-reverse s))) "Elapsed time: 2.167 msecs" nil So, back-of-the-napkin, adding the protocol adds about 25% overhead. For comparison, with the built-in reverse and no O(1) performance, you get 348.634 msecs. Even if the vector is (random example) 30 elements, you get 11.559 msecs. Also, the protocol cost pretty much disappears when you work with a list (that is, comparing (seq-reverse l) and (reverse l) where l is a list of 30 or 1000 elements. In sum, from a performance perspective, implementing these with protocols doesn't hurt reverse at all, and even only hurts rseq a tiny bit. Gary ... To dupe, this is my really-fast definition of seq-reverse, based on the source of rseq and reverse. I didn't take the time to see if the type hints were still useful in the protocol version; and I added the clojure.lang.Reversable thing as an idle gesture, since that might be more appropriate for a real story. => (defprotocol SEQ (seq-reverse [coll])) => (extend-type clojure.lang.IPersistentVector (seq-reverse [^clojure.lang.Reversible rev] (. rev (rseq)))) => (extend-type java.lang.Object SEQ (seq-reverse [coll] (reduce conj () coll))) => (extend-type clojure.lang.Reversible SEQ (seq-reverse [^clojure.lang.Reversible rev] (. rev (rseq)))) -- 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