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 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
--- 
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to