Monthly Archives: January 2010

Clojure Concurrency

For a seminar at university I had to write about parallel programming on the JVM with Clojure. Because I am new to Clojure and did not believe all the euphoric statements about Clojure, I did not only prepare a paper and presentation slides, but also a little demo application called Clojure Sheep.

Clojure Sheep is actually based on Rich Hickey’s ant simulation he presented in his Clojure Concurrency talk, but I removed some logic to concentrate more on the concurrency features and to make it easier to also create a version written in Java. My experiences:

  • It’s quite easy to write the code in Clojure (I have to admit of course, that I had the ants source, which made it even easier ;)). You can fully concentrate on the application logic and don’t have to worry about locking. Instead, you are forced to use transactions at the right places.
  • But instead of thinking about locks, you have to think about for which data you want to use which concurrency primitives. For example, if I had used a single ref for the whole 2d vector of cells (instead of using a ref for each cell), this would probably decrease performance a lot.
  • The Java version was much harder to implement. I could not find a good locking strategy that guarantees maximum thoughput but still doesn’t worry me. So, to make the code as easy as in Clojure, I decided to use a global lock for everything. Of course, this destroys performance! (If you have better ideas, tell me. I already got some ideas from the Clojure mailgroup).
  • When testing on a quadcore machine with 1000×1000 cells and 1000 sheep, the Clojure solution performed about 50 times faster (!) than the Java implementation. This is not surprising given the bad locking strategy I have chosen – but it is cool when you think about the programming complexity of both solutions, which are about the same.

Overall, these results encourage me to try out Clojure for Zong! now. I think, I’ll begin to port some of the core code (basic data structures) to Clojure. Because of the immutable and persistent structures, this could already solve our tremendous open problem how to realize undo/redo in a fast and memory-saving way.