Clojure Macro Average Time

22 Nov

In my previous post on binary search I wanted to evaluate performance of two implementations. Clojure provides dotimes and time. Wouldn’t it be nice if we can string them together, parse output from time and calculate average execution time. Checking source of time and poking around I discovered with-out-str macro. It is quite simple. It just dynamically rebinds default output stream *out* to Having this the rest is piece of cake.

 1 (use '[clojure.contrib.str-utils :only (re-split)])
 2 (defmacro time-avg
 3   "Captures time output, parses it and calculates average.
 4   Modeled after with-out-str. Example:
 5   (time-avg
 6      (dotimes [_ 5] (time (.run #(Thread/sleep (rand 100))))))"
 7   [& body]
 8   `(let [s# (]
 9      (binding [*out* s#]
10        ~@body)
11      (let [strng# (str s#)
12            lns# (re-split #"\n" strng#)
13            flt-regex# #"\d+\.\d+"
14            lns-flts# (filter #(re-seq flt-regex# %) lns#)
15            flts# (map 
16              #(Float/parseFloat (first (re-seq flt-regex# %))) 
17              lns-flts#)
18            sum# (reduce + flts#)]
19        (println strng#)
20        (if (seq flts#)
21          (println "\"Average of" (count flts#) "run/s is" 
22               (/ sum# (count flts#)) "msecs\"")))))

Starting on line 11 we parse output using regexes, look for doubles, sum them up and print calculated average. The only thing I stumbled on was using suffix # in macro variable names.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: