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

Reply via email to