On Mon Mar 26 15:15 2012, Cedric Greevey wrote:
> > What you're running into is the overhead of get the root value of vars
> > like swap! and move-up!.  The only way to avoid this is use something
> > like definline.
> 
> I thought that in 1.3 those had been made much faster to access if
> they didn't have ^{:dynamic true} applied to them?


As of Clojure 1.3, by default, vars only have a root value that exists
globally.  When you tag a var as being ^:dynamic, it is allowed to have
thread-local bindings.  However, remember you can always change the
value of a var:

(defn foo [] :foo) ; evaluates to :foo

(defn printfoo [] (println (foo)))

(printfoo) ; prints :foo

(defn foo [] :bar) ; evaluates to :bar

(printfoo) ; prints :bar

As a result, whenever you use a var in a function, the latest value is
retrieved from the var.  This ensures that your function always sees the
latest value that is assigned to the var.  As far as I know, the only
way to avoid this is to use compile-time inlining of the method body.
You can do this with definline:

(definline foo [] :foo) ; evaluates to :foo

(defn printfoo [] (println (foo)))

(printfoo) ; prints :foo

(definline foo [] :bar) ; evaluates to :bar

(printfoo) ; still prints :foo!

As you can see, definline can make code much harder to understand.  It
only really makes sense in tight loops where hot functions are being
repeatedly invoked.  Otherwise, I doubt vars add significant overhead
for most Clojure code.

Sincerely,

Daniel

Attachment: signature.asc
Description: Digital signature

Reply via email to