groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <>
Subject Re: Optimising a Groovy script
Date Wed, 29 Mar 2017 15:46:08 GMT

On 29.03.2017 10:19, Paul Moore wrote:
> On 28 March 2017 at 22:08, Nelson, Erick <> wrote:
>> Try this...
> Thanks for the suggestion - there were some nice improvements in here.
>> def rng = new MersenneTwister()
>> def roll = {
>>         rng.nextInt(6) + rng.nextInt(6) + rng.nextInt(6) + 3
>> }
> You changed my definitions to use "def" here. This seems to be the
> thing that makes the most difference in performance. I'm really
> struggling to find a good explanation as to the effect of using or not
> using "def".

basically it depends on if Groovy thinks there has to be a cast here or 
not and if the primitive optimizations can kick in.

> I had imagined that using "int roll() {..." would be
> better, as it explicitly states the types which would help the
> compiler avoid the need for generic code. Obviously I was wrong, but
> I'm not at all clear why.

yes, it is better, but only if primitive optimizations are working... or 
if you compile static. I haven't looked into why, but in

>         int n = roll()
>         results[n] = results.containsKey(n) ? results[n] + 1 : 1

result is referenced outside the closure and I think that is already 
enough to not have primitive optimizations in use here. Which means you 
have to pay the boxing cost from int to Integer and back to int for 
every call to roll... and then you have again boxing for 
results.containsKey(n) and results[n]= and results[n] + 1. In that case 
it looks really much better to just use Integer from the start, thus def 
has an advantage here.

> Also, if I use "def rng" but keep "int roll()", I get an error "No
> such property: rng". I'm not clear why that is.

you wrote a script, not a class, thus

rng = new MersenneTwister()

will set a variable called rng in the binding, and

int roll() {
     rng.nextInt(6) + rng.nextInt(6) + rng.nextInt(6) + 3

this will use rng from the binding.

def rng = new MersenneTwister()

will make a local variable and leaves the binding rng blank, thus roll 
gets into trouble

> Do you know of a good resource that explains the difference between
> using def and not doing so?

hm... I think the page I wrote back then got lost in the codehaus move :(
bye Jochen

View raw message