Allocation of Lambdas that capture "this"

Zhong Yu zhong.j.yu at gmail.com
Wed Aug 20 23:58:31 UTC 2014


On Wed, Aug 20, 2014 at 5:00 PM, Richard Warburton
<richard.warburton at gmail.com> wrote:
> Hi,
>
> I've recently being using Java 8 in a fairly performance critical project.
> We make extensive use of lambdas to implement callback handlers. For the
> most part this works well and the no-allocation on non-capturing lambdas
> makes for significantly nicer code than implementing the equivalent in Java
> 7.
>
> Unfortunately we still have quite a few callbacks where we capture no local
> variables, but want to refer to a field of the current class or even just
> call a method on the current class. Under the current implementation this
> still seems to require allocation. In our case we've hoisted up the code
> into the constructor and assigned it to a field, we then refer directly to
> the field at the callsite. Here's a pseudocode example just to clarify what
> I'm talking about.
>
> Allocating:
>
> public Foo() {}
>
> public int read() {
>     return queue.read(obj -> {
>         this.doSomethingWith(obj);
>         ...
>     });
> }
>
> Non-allocating:
>
> private final Consumer<Msg> readHandler;
>
> public Foo() {
>     readHandler = obj -> {
>         this.doSomethingWith(obj);
>         ...
>     };
> }
>
> public int read() {
>     return queue.read(readHandler);
> }
>
> Now this isn't the end of the world but it is choosing to write
> non-idiomatic code for purely performance reasons. Maybe I've missed

Lambda field could become an idiom.

Is there any reason not to initialize the field directly? like

public int read() {
    return queue.read(readHandler);
}
final Consumer<Msg> readHandler = (Msg obj)-> {
    this.doSomethingWith(obj);
    ...
};

Zhong Yu
bayou.io

> something here and there are subtleties that I'm missing - I'm always happy
> to be corrected if I've misunderstood something.
>
> I'm sure people have thought about this one before and I'm bring up this
> specific issue not because "it looks like the JDK isn't doing something
> optimal" but because this was a problem in a concrete scenario. I spent a
> few hours this afternoon doing some memory profiling and this pattern was
> responsible for 6 or the top 8 allocation sites.
>
> regards,
>
>   Richard Warburton
>
>   http://insightfullogic.com
>   @RichardWarburto <http://twitter.com/richardwarburto>
>


More information about the lambda-dev mailing list