>> Being lockless seems useful for certain cases (like real-time system as
>> mentioned in the Wikipedia article). But I still could not grasp the idea
>> how it can increase *real* work throughput, as the problem itself mandates a
>> part of the work can only be done in serial.


Well first of all, your solution is horribly slow:

user=> (time (dotimes [x 1000000] (lock-swap! la (fn [o n] n) x)))
"Elapsed time: 43289.909709 msecs"
nil
user=> (def a (atom 0))
#'user/a
user=> (time (dotimes [x 1000000] (swap! a (fn [o n] n) x)))
"Elapsed time: 475.085593 msecs"
nil

But that's probably made worse by the use of reflection, so let's try this:

user=> (defn lock-swap! [^LockAtom lock-atom & rest-args] (locking
lock-atom (apply swap! (.atom lock-atom) rest-args)))
#'user/lock-swap!
user=> (time (dotimes [x 1000000] (lock-swap! la (fn [o n] n) x)))
"Elapsed time: 7596.568038 msecs"
nil

So, still it's 20x slower than straight old swap!

In all the multithreaded code I've worked on (and I've worked on quite
a lot in Clojure), I've never had code inside a swap! that would take
more than ~1ms to execute. In fact, I would say that by using delay,
promise and future, you can implement your "1 hour task" with much
less touching of locks. For instance, a naive implementation of an
image cache may look like this:


(def icache (atom {}))

(defn cache-image [url]
   (swap! icache assoc url (download-image url)))


However, this is going to hit some of the issues you mentioned above.
We're going to re-download images if there was a swap! retry. Well
here's the correct way to go about this (or one of them).

(def icache (atom {}))

(defn cache-image [url]
   (let [f (future (download-image url))]
     (swap! icache assoc url f)))

I'll admit, we'll still try to download the image twice if two people
try to cache the same image at the exact same time but we could get
around that using promise or agents. So in general, your attitude when
using atoms, refs, or agents should be "get in and get out". Don't do
your work inside of swap!, send or alter....

Timothy

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