This is a neat trick that eliminates boxing/unboxing overhead when you are using Integer and all you need is int.
(This of course works for the other java primitives)
Let's do something stupid like summing up two Integers ten million times.
(def times 10000000)
(def w 640)
(def h 480)
(time (dotimes [i times]
(+ w h)))
This little test took around 950ms on my machine.
The w,h values are unboxed from and boxed into Integer classes in order to be used.
Now consider this:
(defmacro w [] `(int 640))
(defmacro h [] `(int 480))
(time (dotimes [i times]
(+ (w) (h))))
This is a very smart macro trick that I read on the Clojure user group. What it does is it substitutes (w) with a java primitive at compile time.
On my machine, the benchmark took around 430ms.
The problem is that it is ugly, but that can be fixed easily.
(defmacro const-int [name val]
`(defmacro ~name [] (list 'int ~val)))
(const-int w 640)
(const-int h 480)
(time (dotimes [i times]
(+ (w) (h))))
Still around 430ms. There is no performace cost because of the way macros are evaluated.
const-int is a macro that creates a macro so our definition looks prettier. The only caveat is you still have to use (w) instead of w.
No comments:
Post a Comment