Hi all,
I was writing some code and became idly curious about making it more
'general' but still performant. Specifically I thought it'd be neat
to auto-generate a series of vector-based operations from a single
specification. So instead of many functions like this by hand:
(defn vadd3 [[^double a1 ^double a2 ^double a3] [^double b1 ^double b2
^double b3]]
[(+ a1 b1) (+ a2 b2) (+ a3 b3)])
I'd instead have a macro generate them. Pretty low level ops (yes not
really suited for clojure but I like exploring the limits) and I was
pretty happy with the performance:
(bench 1e7 (vadd3 [1.1 2.2 3.3] [2.2 3.3 4.4]))
"Elapsed time: 1799.587 msecs"
Here we have my attempt to generalise it:
(defmacro -make-vec-ops
[{:keys [name op start end] :or {start 2}}]
(cons `do (for [n (range start end)]
`(defn ~(str-sym- \v n name)
~name
[[~@(for [x (range n)] (str-sym- "a" x)) :as ~'a]
[~@(for [x (range n)] (str-sym- "b" x)) :as ~'b]]
[~@(for [x (range n)]
`(~op ~(str-sym- "a" x) ~(str-sym- "b" x)))]))))
(bench 1e7 (v3add [1.1 2.2 3.3] [2.2 3.3 4.4]))
"Elapsed time: 2238.391 msecs"
The performacne isn't 'too bad' at 25% lower. But it's frustratingly
close to matching the original too! I tried toying with some other
answers I found about generating type-metadat. Alas, my resulting
macros were either malformed (unsupported binding forms) or didn't
appear to generate anything in the final functions/performance was the
same.
I'd love to be wowed by a simple solution! Heck 'any' solution that
works ;)
As an aside, the macro is pretty ugly... I tried extracting the vector
deconstruction to a second macro, like this
(defmacro -varg [a n]
`(~@(for [x (range n)] (str-sym- a x)) :as ~a))
where str-sym-
(defmacro str-sym- [& args] `(symbol (str ~@args)))
But couldn't quite to get it to work :/
Cheers,
Daniel Grigg
--
--
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/groups/opt_out.