It looks like the new (deftype ..) may be what I am looking for in
terms of binding heterogenous state efficiently.   The matrix function
was just a test case for how to bind state efficiently.   Thanks for
all of the responses.


On Mar 8, 2:57 pm, Jonathan Shore <[email protected]> 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 [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

Reply via email to