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