Hi,
I tried replacing a closure with a dynamically built and evaluated
metafunction but discovered that it was actually slower.
Here's a minimal example:
(defn f1 [x] (fn [y ] (= x y )))
(defn f2 [x] (eval `(fn [y#] (= ~x y#))))
(defn f3 [x] (eval `(fn [y#] (= ~@[x] y#))))
(use 'criterium.core)
(def v nil) ; nil -> same speed.
(let [f (f1 v)] (quick-bench (f v))) ; 7.1ns
(let [f (f2 v)] (quick-bench (f v))) ; 5.4ns
(let [f (f3 v)] (quick-bench (f v))) ; 5.4ns
(def v [10 20]) ; vector -> f2 slower
(let [f (f1 v)] (quick-bench (f v))) ; 6.8ns
(let [f (f2 v)] (quick-bench (f v))) ; 78.0ns
(let [f (f3 v)] (quick-bench (f v))) ; 5.3ns
(def v {10 20}) ; map -> f2 and f3 slower?!
(let [f (f1 v)] (quick-bench (f v))) ; 6.6ns
(let [f (f2 v)] (quick-bench (f v))) ; 151.0ns
(let [f (f3 v)] (quick-bench (f v))) ; 152.0ns
I guess f2 runs this much slower than f1 because it doesn't actually pass a
reference to x when unquoting, but clones the value, which means it needs
to compare the lists element-wise. The other cases all compare the
references which is why the nil case runs at the same speed.
Why does unquoting ~x clone the vector?
And why doesn't splice unquoting ~@[x] appear to clone the vector, but
*does* clone the map?!
Is there a way to pass all values per reference into a quote, to get
exactly the same behaviour as f1?
Cheers,
--
pascal
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.