I'm trying to add an option "message" attribute to the Clojure time macro. Basically I want to add an optional custom message to the output of time. I'm trying to find a bottleneck in my program and having some descriptive messages attached to time's output would be very helpful.
I've tried the following:
;optional argument
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[expr & msg]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " (first ~msg)))
ret#))
and
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
([expr] (time expr ""))
([expr msg]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
ret#)))
Both throw exceptions. How do I make this work?
It throws an exception because msg is a list,
say you call it with,
(time (+ 1 1) "asd")
msg in the macro becomes a function call, ("asd") which fails. Just destructure msg,
[expr & [msg]]
and use
~msg
You can also test how macros are expanded with macroexpand,
(macroexpand '(time (+ 1 1) "asd"))
Also couple of points,
EDIT: time with optional message,
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[expr & [msg]]
(let [msg (if (nil? msg) "" msg)]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
ret#)))
(time (+ 1 1))
"Elapsed time: 0.068 msecs. "
2
(time (+ 1 1) "asd")
"Elapsed time: 0.067 msecs. asd"
2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With