That makes sense. On Fri, Apr 10, 2009 at 6:16 AM, Stephen C. Gilardi <squee...@mac.com> wrote: > > On Apr 10, 2009, at 3:55 AM, Eric Tschetter wrote: > >> Sure enough, I get the same results >> >> user=> (defn as-str >> [& args] >> (apply str (map #(if (instance? clojure.lang.Named %) (name %) %) args))) >> #'user/as-str >> user=> (time (dotimes [i 1000000] (as-str :a))) >> "Elapsed time: 416.497348 msecs" >> nil >> user=> (time (dotimes [i 1000000] (as-str :a 1))) >> "Elapsed time: 1023.526175 msecs" > > Right, I get numbers in the same ballpark on my machine. > >> Apparently >> >> (defmacro as-str3 [& args] >> (cons 'str (map #(if (instance? clojure.lang.Named %) (name %) %) args))) >> >> runs as fast (or minusculy faster) than the original version that you >> posted: >> >> user=> (defn as-str2 >> "With no args, returns the empty string. With one arg, returns its name >> or string representation. (as-str nil) returns the empty string. With >> more than one arg, returns the concatenation of the as-str values of the >> args." >> {:tag String} >> ([] "") >> ([x] >> (if (instance? clojure.lang.Named x) >> (name x) >> (str x))) >> ([x & ys] >> (let [sb (StringBuilder. #^String (as-str x))] >> (doseq [y ys] >> (.append sb (as-str y))) >> (.toString sb)))) >> user=> (time (dotimes [i 1000000] (as-str2 :a))) >> "Elapsed time: 29.844296 msecs" >> user=> (time (dotimes [i 1000000] (as-str2 :a 1))) >> "Elapsed time: 1046.465682 msecs" > > The occurrences of "as-str" near the bottom of the the definition of as-str2 > should be as-str2 instead. > > Also it seems to take a few repetitions of the "dotimes" call for the time > to settle down and become fairly consistent. In all my timings, I've given > what appears to be a representative run, not the first run. > > With the corrected as-str2, I'm getting numbers like these on my machine: > > user=> (time (dotimes [i 1000000] (as-str2 :a))) > "Elapsed time: 28.319 msecs" > user=> (time (dotimes [i 1000000] (as-str2 :a 1))) > "Elapsed time: 325.617 msecs" > >> user=> (defmacro as-str3 [& args] >> (cons 'str (map #(if (instance? clojure.lang.Named %) (name %) %) args))) >> nil >> user=> (time (dotimes [i 1000000] (as-str3 :a))) >> "Elapsed time: 28.533794 msecs" >> nil >> user=> (time (dotimes [i 1000000] (as-str3 :a 1))) >> "Elapsed time: 260.311017 msecs" > > That turns out not to be the same test. The macro as-str3 gets fully > expanded at macro expansion time. At runtime, what you're iterating is the > expansion: > > user=> (as-str3 :a) > "a" > user=> (macroexpand '(as-str3 :a)) > (str "a") > > For literal arguments to as-str3 (as we've used in the micro-benchmark), > doing the operation at macro expansion time is a win. In the general case, > though, we need the as-str facility to evaluate its arguments: > > user=> (def i :a) > #'user/i > user=> (as-str2 i) > "a" > user=> (as-str3 i) > "i" > > Mapping across the arguments needs to be done at runtime (which in this case > means it will be done a million times), not macro expansion time (which in > this case means it will be done once). > >> Which seems to indicate that apply is actually what is slow... > > Using apply appears to be a somewhat slower than a direct call: > > user=> (time (dotimes [i 1000000] (str "a" "b" "c" "d"))) > "Elapsed time: 437.493 msecs" > > user=> (time (dotimes [i 1000000] (apply str ["a" "b" "c" "d"]))) > "Elapsed time: 731.039 msecs" > > user=> (time (dotimes [i 1000000] (apply str "a" "b" ["c" "d"]))) > "Elapsed time: 1061.53 msecs" > > user=> (time (dotimes [i 1000000] (apply str "a" "b" "c" "d" []))) > "Elapsed time: 1301.953 msecs" > > However, the big difference you saw was the macro difference described > above. > > --Steve > >
--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---