Clojure High Performance Programming by Shantanu Kumar
Publisher: Packt Publishing
Clojure has several good introductory books by now. Clojure Programming is a pragmatic introduction that I always recommend to newcomers. The Joy of Clojure is a strong second book on the philosophy of the language. I've enjoyed them both. But as Clojure programs hit the real world we need books like Clojure High Performance Programming. It presents an overview of the performance characteristics of different Clojure constructs, explains basic profiling techniques and optimizations on different levels. Besides introducing an important subject it also deepens the understanding of the Java ecosystem where most Clojure programs live. The book presents a natural next step for the intermediate Clojure programmer.
Over the last two years Clojure has become my primary language of choice. Unless there's a certain library I'd like to utilize in another technology, I go for Clojure in my side projects. The language makes an interesting contrast to my day job where I mainly use C# and Python. While I do enjoy Python, the level of expression and elegance in Clojure often beats it hands down.
The high level of Clojure code is a double edged sword. Programs do get harder to reason about with respect to performance. Partly that's due to the lazy nature of many constructs. Clojure is not lazy by default like Haskell, yet many library functions do produce lazy sequences. Sure, laziness makes algorithms composable and the resulting code often performs well. However, when it doesn't, it's terribly hard to understand why. Even though I spent considerable time optimizing performance in C++ and .Net applications I wasn't as efficient with the task in Clojure as I'd like to be. That was my main motivation to pick-up this book.
Clojure High Performance Programming assumes a working knowledge of Clojure, so little time is spent on introducing basic concepts. Instead we get a detailed treatment on the performance characteristics of individual data structures (both Clojure's and some Java collections), discussions on laziness, memoization and mutability by transients. A particularly strong part of the book is it's coverage of Clojure's concurrency support. This coverage includes the sparsely documented core.reducers library and interesting details on the agents and software transactional memory implementations. In addition, the book gives a brief introduction to performance bottlenecks in general, based on a discussion of host performance and the underlaying hardware, and short recommendations on available profiling tools.
The book does an excellent job of providing an overview of the topics. I was pleasantly surprised that the author dives deeper than existing documentation and, on multiple occasions, discusses the actual implementation in Clojure's core. The author understands his subject and clearly put a lot of effort behind it. I enjoyed his writing style and the key points are well communicated. On the negative side the organization of the book could be improved. It has several rough context switches and some material would benefit from a re-organization. Perhaps this is inevitable given the broad scope of the book crammed into a mere 150 pages. That said, if you've started with Clojure and intend to use it for larger programs this book is a valuable read.
Reviewed April 2014