(def *dosync-counts* (atom {})
(defn avg-in [map key val]
  (let [[avg cnt] (get map key [0 0])]
    (assoc map key [(/ (+ (* avg cnt) val) (inc cnt)) (inc cnt)])))

(defmacro logged-dosync [& body]
  `(let [count# (atom 0)]
     (dosync
       (swap! count# inc)
       ~...@body)
     (swap! *dosync-counts* avg-in (quote ~body) (deref count#))))

(defn crude-print-dosync-log []
  (doseq [[code [avg cnt]] @*dosync-counts*]
    (println code)
    (println avg "retries on average over" cnt "total transaction(s)")
    (println)))

These tools should suffice to simply discover how many retries some
transaction is taking on average. For more complex dosync profiling you'd
probably need hooks deeper into Clojure's STM, particularly for logging what
ref value changed to cause a retry or similarly.

(A cleverer macro might parse the body for ensures, commutes, and the like,
and bookend the body with code to record the at-start-of-transaction values
of the involved refs and code to compare these against the out-transaction
values just before commit, getting the latter using (future (deref foo)) or
some similar method that will see the out-transaction values, and note any
that had changed. So hooks deeper into STM might not be necessary after all,
at least for some simple tests of why a retry might have happened. Having
code that can introspect on code and write code seems to allow for some
serious kung-fu!)

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to