By the way, I also noticed your logic is wrong. It should be (+ (* i ncol) j) rather than (* i j).
-Per On Tue, Mar 9, 2010 at 2:57 AM, Jonathan Shore <jonathan.sh...@gmail.com> wrote: > Hi, > I'm still trying to work out the best way to deal with operations on > heterogenous data in clojure. I have a complex application which has such > requirements. I wrote a simple toy matrix as a means to explore closure > versus map based implementations. Note that in this case the "data > structure" is not pure, rather mutable. Here are 2 implementations I came > up with (note this is my second day with closure, so my not be idiomatic): > The first impl uses closures and provides access via a function (is there a > more efficient way to do this?, avoiding the cond-dispatch?): > > (defn matrix-1 [nrow ncol] > (let [data (float-array (* nrow ncol))] > (fn [command & args] > (condp = command > :dim > [nrow ncol] > :get > (let [[i j] args] (aget data (* i j))) > :set > (let [[i j v] args] (aset-float data (* i j) v)))))) > > The second implementation uses a map: > (defn matrix-2 [nrow ncol] > { :data (float-array (* nrow ncol)), :nrow nrow, :ncol ncol }) > (defn mset! [mat i j v] > (aset-float (get mat :data) (* i j) v)) > (defn mget [mat i j] > (aget (get mat :data) (* i j))) > > (defn mdim [mat] > [(get mat :nrow) (get mat :ncol)]) > Both of these implementations bother me. The first because of the dispatch, > the second because maps clearly are not "near the metal". It would seem > would have to resort to java side classes, unless there is a better way? > BTW, the map implementation is about 3x faster: > (def m1 (matrix-1 10 10)) > (def m2 (matrix-2 10 10)) > ... > (defn benchmark [what times f] > (let [ > Tstart > (System/currentTimeMillis) > result > (loop [ntimes times] > (f) > (if (> ntimes 0) > (recur (- ntimes 1)))) > Tend > (System/currentTimeMillis)] > (println "evaluating" what "took" (- Tend Tstart) "ms"))) > (benchmark "map-based-matrix" 1000000 (fn [] (mset! m2 3 3 0.1234))) > (benchmark "closure-based-matrix" 1000000 (fn [] (m1 :set 3 3 0.1234))) > > > > > > -- > 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 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