Interesting.... 在 2012年3月4日星期日UTC+8上午8时56分56秒,Mikhail Kryshen写道: > > If I understand Clojure's dynamic vars correctly, in a context where some > var *bar* is already thread-bound, the following code: > > (binding [*bar* new-val] > (foo)) > > is semantically equivalent to: > > (let [old-val *bar*] > (set! *bar* new-val) > (try > (foo) > (finally > (set! *bar* old-val)))) > > The latter version appears to be 3 to 4 times faster if (foo) does nothing. > > The binding macro in the first version expands to something like: > > (push-thread-bindings (hash-map (var *bar*) new-val)) > (try > (foo) > (finally (pop-thread-bindings))) > > So the binding macro uses some stack implementation instead of just > remembering the old value on the JVM call stack like the faster version > does. I am probably missing something, but why do dynamic vars need to > have their own stack for bindings? > > Also I noticed that replacing "(hash-map (var *bar*) new-val)" with > "{(var *bar*) new-val}" in the above macro expansion makes it about 1.5-2 > times faster. This could also be fixed in the source of the binding > defmacro by changing the following line: > > (push-thread-bindings (hash-map ~@(var-ize bindings))) > > to: > > (push-thread-bindings ~(apply hash-map (var-ize bindings))) > > -- > Mikhail > >
-- 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 Note that posts from new members are moderated - please be patient with your first post. 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