Hi all, I was playing with the defprotocol/deftype/reify stuff in 1.2,
and I wanted to test how a common abstraction I use would look if I
did with java data structures vs. clojure ones. I've pasted the code
below. I'll wait for you to take a look....So on my test, I have the
Clojure version about 5x slower than the Java one only one cpu. Now I
know that JavaMapCounter isn't thread safe, while ClojureCounter is,
and that if I had sufficiently many cpus, the clojure version would be
faster. But is there a better way to do what I'm doing with clojure to
get the performance a bit more up to par with javas?
Thanks, Aria
(defprotocol Counter
(getCount [_ k])
(incCount! [_ k v])
(totalCount [_]))
(defn JavaMapCounter []
(let [counts (java.util.HashMap.)
total (org.apache.commons.lang.mutable.MutableDouble.)]
(reify :as self
Counter
(getCount [k] (.get counts k))
(incCount! [k v]
(let [cur-v (if-let [x (getCount self k)] x 0.0)]
(.put counts k (+ v cur-v)))
(.setValue total (+ (.doubleValue total) v)))
(totalCount [] (.doubleValue total)))))
(defn ClojureCounter []
(let [state (atom {:counts (hash-map) :total 0.0})]
(reify :as self
Counter
(getCount [k] (if-let [x (get-in @state [:counts,k])] x 0.0))
(incCount! [k v]
(swap! state
(fn [data]
(let [add-v (fn [x] (if x (+ x v) v))]
(-> data (update-in [:counts,k] add-v)
(update-in [:total] add-v))))))
(totalCount [] (:total @state)))))
(defn testCounter [counter]
(let [r (java.util.Random. 0)]
(dotimes [_ 1000000]
(incCount! counter (.nextInt r 100000) (.nextDouble r)))))
(time (testCounter (JavaMapCounter)))
(time (testCounter (ClojureCounter)))
--
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