Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does scala cache conversions to functional interfaces

Scala 2.12 can automatically convert a lambda expression to an interface. E.g, I'm using:

import org.apache.kafka.common.serialization.{Deserializer, Serde, Serializer}
import scalapb.GeneratedMessageCompanion

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

  override def deserializer(): Deserializer[A] = (_: String, data: Array[Byte]) => companion.parseFrom(data)
}

Will it automatically cache the instance of the created objects, so that a new object isn't allocated on every call. I.e. I want:

import org.apache.kafka.common.serialization.{Deserializer, Serde, Serializer}
import scalapb.GeneratedMessageCompanion

class ProtoSerde[A <: scalapb.GeneratedMessage](implicit companion: GeneratedMessageCompanion[A])
  extends Serde[A] {
  lazy val _serializer: Serializer[A] = (_: String, data: A) => data.toByteArray
  lazy val _deserializer: Deserializer[A] = (_: String, data: Array[Byte]) => companion.parseFrom(data)

  override def serializer(): Serializer[A] = _serializer

  override def deserializer(): Deserializer[A] = _deserializer
}

Will the compiler perform this optimization automatically, or do I have to do it myself?

like image 675
Yair Halberstadt Avatar asked Sep 06 '26 02:09

Yair Halberstadt


2 Answers

def is not memoized to calling it will recompute value every time. It might be later optimized by JIT compiler.

But there's a simpler solution to make properties of class memoized. Scala allows changing def to val while you override parent methods. It is also possible to add lazy modifier on extending class:

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)
}
like image 104
Krzysztof Atłasik Avatar answered Sep 07 '26 21:09

Krzysztof Atłasik


Compiler doesn't perform such optimizations. Conversion lambda expression to an interface doesn't mean saving instance of that interface as a singleton or any another way to save that. It will create this instance every time when you call this lambda. You need to do this optimization by yourself.

like image 45
Boris Azanov Avatar answered Sep 07 '26 21:09

Boris Azanov