Simple comparison of Future/Promises APIs in Java, GPars, Google Guava, Akka and Finagle/Util.
This is a simple and small weekend project to explore the different APIs for Futures/Promises in various JVM languages. Recently, I noticed that many concurrency libraries for the JVM seem to share some similarities in terms of their APIs and constructs. Thus, I decided to explore those APIs and constructs more. I chose to focus on the following main libraries in the three main JVM languages, i.e, Java, Groovy and Scala.
I wanted a small enough example that it would be easy to write and compare the different APIs. Prior to this, I was a technical reviewer for the book Parallel Programming with Microsoft .NET. In that book, there was a chapter that focused on the Futures API for .NET. I used that example as the basis of this project. I just stripped out the UI layer to make things simpler. The application simulates reading some data from the stock exchange and comparing it to historical data to make some predictions on purchasing. The application itself does not perform any real calculations but uses busy waiting/thread sleep to simulate activity.
Here's the code snippet to illustrate the core of the application:
By the way, while this project focuses on JVM languages, the .NET book is also worth skimming just to see how Futures work in the .NET framework.
Since I derived my example from the Parallel Programming with Microsoft .NET book, this project is also licensed under the Microsoft Patterns & Practices License.
Well, not surprisingly the majority of the APIs were very similar. All of them offer some way to wait for the results of a Future. All of them offer some way to compose/chain different futures together. And while my simple example does not illustrate this, most of them offer some way to handle errors in a systematic manner.
One very annoying consequence of parallelizing the application is that the parallelized version ends up being a lot longer and more verbose compared to the original sequential version. Unsurprisingly, the Java versions are the most verbose. The two Scala versions are comparable. The Groovy version was not only the shortest but might actually be the easiest to read. Here are the code snippets for the core of the application:
Each library performed comparably. You can find the running times for the application collected through Google Caliper at http://bit.ly/LdJE2f. The raw running times are probably meaningless since this is a toy application. What is more interesting in the relative running times.
Here's a screenshot to show you the results as rendered by the Google Caliper benchmark app
This is my first experience with some of the libraries so the way I coded the example might not be very idiomatic. In particular, I am not very fluent in Scala so the way I code might not be representative of the way Scala hackers code.