scala是否缓存到功能接口的转换

scala是否缓存到功能接口的转换,scala,lambda,functional-interface,single-abstract-method,Scala,Lambda,Functional Interface,Single Abstract Method,Scala 2.12可以自动将lambda表达式转换为接口。例如,我正在使用: import org.apache.kafka.common.serialization.{Deserializer,Serde,Serializer} 导入scalapb.GeneratedMessageCompanion 类ProtoSerde[A data.toByteArray override def反序列化器():反序列化器[A]=(字符串,数据:数组[Byte])=>companion.parseFro

Scala 2.12可以自动将lambda表达式转换为接口。例如,我正在使用:

import org.apache.kafka.common.serialization.{Deserializer,Serde,Serializer}
导入scalapb.GeneratedMessageCompanion
类ProtoSerde[A data.toByteArray
override def反序列化器():反序列化器[A]=(字符串,数据:数组[Byte])=>companion.parseFrom(数据)
}
它会自动缓存已创建对象的实例,以便不会在每次调用时分配新对象。例如,我希望:

import org.apache.kafka.common.serialization.{Deserializer,Serde,Serializer}
导入scalapb.GeneratedMessageCompanion
类ProtoSerde[A data.toByteArray
lazy val_反序列化程序:反序列化程序[A]=(字符串,数据:数组[Byte])=>companion.parseFrom(数据)
重写def序列化程序():序列化程序[A]=\U序列化程序
重写def反序列化程序():反序列化程序[A]=\U反序列化程序
}

编译器会自动执行此优化,还是我必须自己执行此优化?

编译器不会执行此类优化。将lambda表达式转换为接口并不意味着将该接口的实例保存为单例或任何其他保存方式。每次调用此lambda时,它都会创建此实例。您需要自己进行此优化。

def
不会被记录为每次调用它都会重新计算值。它可能稍后由JIT编译器进行优化

但有一个更简单的解决方案可以使类的属性记忆。Scala允许在重写父方法时将
def
更改为
val
。还可以在扩展类时添加
lazy
修饰符:

class ProtoSerde[A <: scalapb.GeneratedMessage](implicit companion: GeneratedMessageCompanion[A])
  extends Serde[A] {
  override lazy val serializer: Serializer[A] = (_: String, data: A) => data.toByteArray

  override lazy val deserializer: Deserializer[A] = (_: String, data: Array[Byte]) => companion.parseFrom(data)
}
class ProtoSerde[A data.toByteArray
重写lazy val反序列化器:反序列化器[A]=(uxAE:字符串,数据:数组[Byte])=>companion.parseFrom(数据)
}

也许最好在您的特定环境中进行基准测试

trait Quxable[A] {
  def qux(x: A): A
}

class FooImpl1 {
  def zar(): Quxable[Int] = (x: Int) => x + 1
}

class FooImpl2 {
  val _zar: Quxable[Int] = (x: Int) => x + 1
  def zar(): Quxable[Int] = _zar
}

// sbt "jmh:run -i 5 -wi 5 -f 2 -t 1 -prof gc bench.So61983239"

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.Throughput))
class So61983239 {
  val end = 1000000
  val fooImpl1 = new FooImpl1
  val fooImpl2 = new FooImpl2

  @Benchmark def impl1 = (1 to end) map (x => fooImpl1.zar().qux(x))
  @Benchmark def impl2 = (1 to end) map (x => fooImpl2.zar().qux(x))
}
为两者提供类似的分配率(
gc.alloc.rate


它比这更复杂。最后它是一个实现细节,但并非在所有情况下都会创建类,甚至可能会缓存。请参阅Brian Goetz的Lambda表达式翻译:
[info] Benchmark                                           Mode  Cnt         Score         Error   Units
[info] So61983239.impl1                                   thrpt   10        76.866 ±       2.690   ops/s
[info] So61983239.impl1:·gc.alloc.rate                    thrpt   10      4790.899 ±     167.414  MB/sec
[info] So61983239.impl1:·gc.alloc.rate.norm               thrpt   10  68637392.621 ±       0.152    B/op
[info] So61983239.impl1:·gc.churn.PS_Eden_Space           thrpt   10      4793.715 ±     174.955  MB/sec
[info] So61983239.impl1:·gc.churn.PS_Eden_Space.norm      thrpt   10  68686591.527 ± 1866568.380    B/op
[info] So61983239.impl1:·gc.churn.PS_Survivor_Space       thrpt   10         6.216 ±       1.411  MB/sec
[info] So61983239.impl1:·gc.churn.PS_Survivor_Space.norm  thrpt   10     89091.175 ±   20368.810    B/op
[info] So61983239.impl1:·gc.count                         thrpt   10       234.000                counts
[info] So61983239.impl1:·gc.time                          thrpt   10      1055.000                    ms
[info] So61983239.impl2                                   thrpt   10        78.027 ±       0.889   ops/s
[info] So61983239.impl2:·gc.alloc.rate                    thrpt   10      4862.226 ±      54.507  MB/sec
[info] So61983239.impl2:·gc.alloc.rate.norm               thrpt   10  68637392.613 ±       0.162    B/op
[info] So61983239.impl2:·gc.churn.PS_Eden_Space           thrpt   10      4895.604 ±     148.716  MB/sec
[info] So61983239.impl2:·gc.churn.PS_Eden_Space.norm      thrpt   10  69105653.917 ± 1668136.154    B/op
[info] So61983239.impl2:·gc.churn.PS_Survivor_Space       thrpt   10         5.582 ±       2.634  MB/sec
[info] So61983239.impl2:·gc.churn.PS_Survivor_Space.norm  thrpt   10     78851.978 ±   37413.327    B/op
[info] So61983239.impl2:·gc.count                         thrpt   10       230.000                counts
[info] So61983239.impl2:·gc.time                          thrpt   10      1073.000                    ms