Tuesday, September 11, 2012

Imperative vs functional programming style (Part II)

In the previous post we saw how it's much nicer (and much easier to test) when we break up our functionality in small chunks that we can easily reuse in different contexts. Let's spice up the same example a bit, this time using Groovy:


Now we are going through a much bigger list of artists and it actually would make a huge difference if we could parallelize the work as much as possible.
Fortunately, this is quite easy with Groovy and the GPars library:
Dealing with data frequently involves manipulating collections. Lists, arrays, sets, maps, iterators, strings and lot of other data types can be viewed as collections of items. The common pattern to process such collections is to take elements sequentially, one-by-one, and make an action for each of the items in row. 
Take, for example, the min() function, which is supposed to return the smallest element of a collection. When you call the min() method on a collection of numbers, the caller thread will create an accumulator or so-far-the-smallest-value initialized to the minimum value of the given type, let say to zero. And then the thread will iterate through the elements of the collection and compare them with the value in the accumulator . Once all elements have been processed, the minimum value is stored in the accumulator . 
This algorithm, however simple, is totally wrong on multi-core hardware. Running the min() function on a dual-core chip can leverage at most 50% of the computing power of the chip. On a quad-core it would be only 25%. Correct, this algorithm effectively wastes 75% of the computing power of the chip.

Now, each query is invoked asynchronously which makes the processing much faster and efficient without making the code more complex.

No comments:

Post a Comment