A page has been added to our benchmark results reports showing the
results possible when using the "fat-free" form:

https://apache.github.io/groovy/dev/bench/jmh-adhoc/

Cheers, Paul.

On Mon, Jun 1, 2026 at 8:32 PM Paul King <[email protected]> wrote:
>
> I created 17 new overloads for "fat-free" variants that can hook up
> with "curryWith" (GROOVY-12043).
> And 4 of the "With" style but not using that suffix - all marked @Incubating.
> This was all I had planned for Groovy 6.0.X at this stage. Feedback welcome.
> We can always add more if feedback shows that our users opt for this
> slightly different style for the performance gains it offers.
>
> https://issues.apache.org/jira/browse/GROOVY-12054
>
> There is also an optimization for CurriedClosure for the simple case
> (1-arg) in GROOVY-12044.
> I haven't tried to do further CurriedClosure optimisations at this stage.
>
> Cheers, Paul.
>
> On Sun, May 24, 2026 at 12:46 AM Jochen Theodorou <[email protected]> wrote:
> >
> > Hi Paul,
> >
> >
> > I think we have to separate memory consumption and performance a bit
> > here. Of course allocating in a loop costs performance compared to not
> > allocating. Creating new objects is not exactly cheap on the JVM, so
> > here the two touch  for this case.
> >
> > For example the case of performance cost for CurriedClosure. Yes, we
> > rewrap the array and thus we create a ton of useless Objects. But do we
> > really have to? I think not. Nothing except manpower, time and
> > motivation stops us from collapsing CurriedClosures. This can partially
> > happen at construction time, partially this can happen at the callsite
> > itself. And interestingly, we probably could even save on some guards..
> > Actually there is some space for optimization in general. But this does
> > not solve the problem of if you create the CurriedClosure inside the hot
> > loop. Then you still carry the cost of creating lots of CurriedClosure
> > objects.
> >
> > Quite some time ago I was toying with the idea of having a special
> > non-capturing Closure, that is incompatible with the capturing Closure.
> > Why? then for example a builder can make it clear by signature that it
> > will require a delegate, or something like findAll can make it clear,
> > that there will be no use of delegation. Well, that was an idea, did not
> > get very far with it. I feel there is quite a bit optimization potential
> > here as well - similar to non capturing lambdas. But if you then go and
> > pack everything in a Closure as it is today, it won't got far I think.
> >
> > Which is also why this works with lambdas in static compilation, but not
> > in dynamic Groovy... unless we fundamentally change the way these things
> > are done. For example in "words.findAll(String::startsWith, 'A')", we
> > could in theory just have a reusable wrapper for a MethodHandle, even
> > create the wrapper at the callsite only (and keep it there) to tailor it
> > to what we require for the method we call it with... hmm... that is
> > similar to what is done for lambdas I think... just not as dynamic.
> >
> > Then there is the aspect of "looks". findAll with 2 parameters looks a
> > bit odd on first look. But maybe that is something getting used too?
> >
> > bye Jochen
> >
> > On 5/23/26 14:53, Paul King wrote:
> > > Hi folks,
> > >
> > > Donald Raab of Eclipse Collections fame, did a recent blog post about
> > > what that library has done for better performance:
> > >
> > > https://donraab.medium.com/fat-free-lambdas-in-java-bf228da0613b
> > >
> > > Donald sent me a private message asking about Groovy's take on some of
> > > those optimisations, so I thought it might be interesting to analyse
> > > things. Past optimisation work, and the recent work Daniel did on
> > > optimizing non-capturing lambdas put Groovy on a good footing for some
> > > metrics but for many of our DGM methods that take Closures, we have
> > > ways (with varying degrees of impact) to make things more performant.
> > >
> > > I did a benchmark and the results are in:
> > >
> > > https://issues.apache.org/jira/browse/GROOVY-12034
> > >
> > > There is a PR but currently the PR is just the benchmark tests
> > > themselves, not any code changes at present:
> > >
> > > https://github.com/apache/groovy/pull/2557
> > >
> > > I'd encourage folks to read that ticket, we have a few options we
> > > might want to explore.
> > >
> > > TL;DR
> > > * there are a few potential optimsations we might be able to apply for
> > > existing code
> > > * we might want to consider a curryWith method, kind of a lazy rcurry
> > > * we might want to consider the equivalent of Eclipse Collections
> > > "*With" method variants. Instead of "words.findAll{ it.startsWith('A')
> > > }" we'd have a variant "words.findAll(String::startsWith, 'A')
> > >
> > > Anyway, I'll ponder things a bit more and make some follow-up
> > > PRs/emails. The analysis suggests just creating the extra variants on
> > > a handful of the most widely used DGM methods. But feedback is most
> > > welcome.
> > >
> > > Cheers, Paul.
> >

Reply via email to