首页 > 解决方案 > Kotlin 是否优化了 JVM 中 lambda 的创建?

问题描述

我有一个如下所示的代码:

infix fun <T> Option<T>.valueIs(value : T): Pair<() -> Boolean,Set<Node>> {
    val function = {this.selectedValue == value}
    val parents = setOf(this)
    return Pair(function, parents)
}

val function = {this.selectedValue == value}我的问题是,每次调用此扩展函数时,Kotlin 是否总是会在 JVM 中创建一个匿名对象,或者它是否具有某种优化以重用它(如果this并且value相同)。

标签: kotlinlambdajvm

解决方案


Kotlin 和 Java 一样,如果您的 lambda 不访问(也称为“捕获”)在其外部声明的变量(包括 ),则可以避免每次创建新对象this{this.selectedValue == value}捕获thisand value,所以它没有。

你可以想象一些缓存将捕获的变量映射到 lambda 实例,所以它很有效

private val lambdas = mutableMapOf<Any, () -> Boolean>()

infix fun <T> Option<T>.valueIs(value : T): Pair<() -> Boolean,Set<Node>> {
    val function = lambdas.getOrUpdate(Pair(this, value)) {this.selectedValue == value}
    val parents = setOf(this)
    return Pair(function, parents)
}

但:

  1. 它可以防止 lambdas 被垃圾收集,以防万一你用相同的方法调用该方法thisvalue可以通过使用来修复WeakHashMap);

  2. 即使忽略这一点,这也不是微不足道的开销;

  3. 它要求任何捕获的值都表现良好hashCode并且equals. 好的,无论如何他们都应该拥有它们,但是如果他们不这样做,请想象一下调试时会出现问题!

Kotlin 有另一种非常重要的方法来避免为 lambdas 创建对象:将它们作为参数传递给inline函数。当然,当您想将 lambda 放入数据结构(甚至像Pair.


推荐阅读