Your code in Groovy can be just as fast as code written in Java, Scala or any other programing language.
This should not be surprising, since GPars is technically a solid tasty Java-made cake with a Groovy DSL cream on it.

Unlike in Java, however, with GPars, as well as with other DSL-friendly languages, you are very likely to experience a useful kind of code speed-up for free,
a speed-up coming from a better and cleaner design of your application. Coding with a concurrency DSL will give you smaller code-base with code
using the concurrency primitives as language constructs. So it is much easier to build robust concurrent applications, identify potential
bottle-necks or errors and eliminate them.

While this whole User Guide is describing how to use Groovy and GPars to create beautiful and robust concurrent code, let's use this chapter
to highlight a few places, where some code tuning or minor design compromises could give you interesting performance gains.

h3. Parallel Collections
Methods for parallel collection processing, like _eachParallel()_ , _collectParallel()_ and such use _Parallel Array_ , an efficient tree-like data structure behind the scenes.
This data structure has to be built from the original collection each time you call any of the parallel collection methods.
Thus when chaining parallel method calls you might consider using the _map/reduce_ API instead or resort to using the _ParallelArray_ API directly, to avoid the _Parallel Array_ creation overhead.

{code}
GParsPool.withPool {
    people.findAllParallel{it.isMale()}.collectParallel{it.name}.any{it == 'Joe'}
    people.parallel.filter{it.isMale()}.map{it.name}.filter{it == 'Joe'}.size() > 0
    people.parallelArray.withFilter({it.isMale()} as Predicate).withMapping({it.name} as Mapper).any{it == 'Joe'} != null
}
{code}

In many scenarios changing the pool size from the default value may give you performance benefits. Especially if your tasks
perform IO operations, like file or database access, networking and such, increasing the number of threads in the pool is likely to help performance.

{code}
GParsPool.withPool(50) {
    ...
}
{code}

Since the closures you provide to the parallel collection processing methods will get executed frequently and concurrently,
you may further slightly benefit from turning them into Java.

h3. Actors

GPars actors are fast. _DynamicDispatchActors_ and _ReactiveActors_ are about twice as fast as the _DefaultActors_ , since they don't have to maintain
an implicit state between subsequent message arrivals. The _DefaultActors_ are in fact on par in performance with actors in _Scala_ , which you can hardly hear of as being slow.

If top performance is what you're looking for, a good start is to identify the following patterns in your actor code:
{code}
actor {
    loop {
        react {msg ->
            switch(msg) {
                case String:...
                case Integer:...
            }
        }
    }
}
{code}
and replace them with _DynamicDispatchActor_ :
{code}
messageHandler {
    when{String msg -> ...}
    when{Integer msg -> ...}
}
{code}

The _loop_ and _react_ methods are rather costly to call.

Defining a _DynamicDispatchActor_ or _ReactiveActor_ as classes instead of using the _messageHandler_ and _reactor_ factory methods will also give you some more speed:

{code}
class MyHandler extends DynamicDispatchActor {
    public void handleMessage(String msg) {
        ...
    }

    public void handleMessage(Integer msg) {
        ...
    }
}
{code}

Now, moving the _MyHandler_ class into Java will squeeze the last bit of performance from GPars.

h4. Pool adjustment

GPars allows you to group actors around thread pools, giving you the freedom to organize actors any way you like.
It is always worthwhile to experiment with the actor pool size and type. _FJPool_ usually gives better characteristics that
_DefaultPool_ , but seems to be more sensitive to the number of threads in the pool.
Sometimes using a _ResizeablePool_ or _ResizeableFJPool_ could help performance by automatic eliminating unneeded threads.

{code}
def attackerGroup = new DefaultPGroup(new ResizeableFJPool(10))
def defenderGroup = new DefaultPGroup(new DefaultPool(5))

def attacker = attackerGroup.actor {...}
def defender = defenderGroup.messageHandler {...}
...
{code}

h3. Agents

GPars _Agents_ are even a bit faster in processing messages than actors. The advice to group agents wisely around thread pools
and tune the pool sizes and types applies to agents as well as to actors.
With agents, you may also benefit from submitting Java-written closures as messages.

h3. Share your experience

The more we hear about GPars uses in the wild the better we can adapt it for the future. Let us know how you use GPars and how it performs.
Send us your benchmarks, performance comparisons or profiling reports to help us tune GPars for you.

