capturing lambdas 捕获和非捕获的Lambda表达式

Capturing versus non-capturing lambdas

Lambdas are said to be "capturing" if they access a non-static variable or object that was defined outside of the lambda body. For example, this lambda captures the variablex:

int x = 5; return y -> x + y;

In order for this lambda declaration to be valid, the variables it captures must be "effectively final". So, either they must be marked with thefinalmodifier, or they must not be modified after they’re assigned.

Whether a lambda is capturing or not has implications for performance. A non-capturing lambda is generally going to be more efficient than a capturing one. Although this is not defined in any specifications (as far as I know), and you shouldn’t count on it for a program’s correctness, a non-capturing lambda only needs to be evaluated once. From then on, it will return an identical instance. Capturing lambdas need to be evaluated every time they’re encountered, and currently that performs much like instantiating a new instance of an anonymous class.

捕获和非捕获的Lambda表达式

当Lambda表达式访问一个定义在Lambda表达式体外的非静态变量或者对象时,这个Lambda表达式称为“捕获的”。比如,下面这个lambda表达式捕捉了变量x:

int x = 5; return y -> x + y;为了保证这个lambda表达式声明是正确的,被它捕获的变量必须是“有效final”的。所以要么它们需要用final修饰符号标记,要么保证它们在赋值后不能被改变。

Lambda表达式是否是捕获的和性能悄然相关。一个非不捕获的lambda通常比捕获的更高效,虽然这一点没有书面的规范说明(据我所知),而且也不能为了程序的正确性指望它做什么,非捕获的lambda只需要计算一次. 然后每次使用到它都会返回一个唯一的实例。而捕获的lambda表达式每次使用时都需要重新计算一次,而且从目前实现来看,它很像实例化一个匿名内部类的实例。

Lambda的性能

Oracle公司 性能比较的文档: JDK 8: Lambda Performance study, 详细而全面的比较了lambda表达式和匿名函数之间的性能差别。

lambda开发组也有一篇ppt, 其中也讲到了lambda的性能(包括capture和非capture的情况)。 lambda最差的情况性能内部类一样,, 好的情况肯定比内部类性能高。

Java 8 Lambdas – they are fast, very fast。Java 8 Lambda Performance Comparison

https://github.com/LMAX-Exchange/disruptor/wiki/Getting-Started 上面也有一段关于这方面的提示:

This would create a capturing lambda, meaning that it would need to instantiate an object to hold theByteBuffer bb variable as it passes the lambda through to thepublishEvent() call. This will create additional (unnecessary) garbage, so the call that passes the argument through to the lambda should be preferred if low GC pressure is a requirement.

Give that method references can be used instead of anonymous lamdbas it is possible to rewrite the example in this fashion.

所以我们还是尽量用方法引用吧。

相关讨论:

/*** java capturing lambda 性能讨论:应该避免capturing lambda应用* * @see *

版权声明:本文为博主原创文章,未经博主允许不得转载。

只是需要垮上后座的勇气和一颗想走即走的心,

capturing lambdas 捕获和非捕获的Lambda表达式

相关文章:

你感兴趣的文章:

标签云: