Reputation: 111
I have a random number class which generate the random number.However i want it to be Initiate as class member so that we do not need to regenerate in every call.Below is the code at present.
import ml.combust.mleap.core.Model
import ml.combust.mleap.core.types._
case class RandomNumberModel() extends Model{
def apply(input: String): Double = {
val rnd = scala.util.Random
return rnd.nextFloat
}
override def inputSchema: StructType = StructType("input" -> ScalarType.String).get
override def outputSchema: StructType = StructType("output" -> ScalarType.Double ).get
}
I am new to scala need suggestion What changes i have to do here ?
Upvotes: 0
Views: 94
Reputation: 170835
This is mostly a response to your own answer, but doesn't fit in a comment.
Scala has a built-in and thread-safe alternative to what you do with var _instance
and def instance
: lazy val
. Using it we get
object RandomNumberModel {
// private is still visible in the companion class
private lazy val instance : Random = scala.util.Random
}
// in the class:
val inst = RandomNumberModel.instance
Since you always need to initialize the instance when you use RandomNumberModel
, you actually don't get any benefit from lazy
for this case, only some minor overhead. Non-lazy val
s in the companion object are only initialized when the class is loaded, e.g. when you create the first instance of the class. So just do private val instance : Random = scala.util.Random
.
You don't need to store a reference which always points to the same instance in the class, this just wastes memory. Better use RandomNumberModel.instance
directly
case class RandomNumberModel() extends Model{
def apply(input: String): Double = {
RandomNumberModel.instance.nextFloat // why not nextDouble?
}
...
}
You have multiple models using the same Random
. If your program ever has multiple threads manipulating models, note
If you use ThreadLocalRandom
it handles the initialization itself:
case class RandomNumberModel() extends Model{
def apply(input: String): Double = {
ThreadLocalRandom.current.nextFloat
}
...
}
// object RandomNumberModel is gone
Do you want all RandomNumberModel
s to be equal? If not, don't make it case class
.
Upvotes: 1
Reputation: 111
I tried as below will this work fine or here i am doing anything wrong:
case class RandomNumberModel() extends Model{
import RandomNumberModel._
val inst = instance()
def apply(input: String): Double = {
inst.nextFloat
}
override def inputSchema: StructType = StructType("input" -> ScalarType.String).get
override def outputSchema: StructType = StructType("output" -> ScalarType.Double ).get
}
object RandomNumberModel {
private var _instance : Random = null
def instance() = {
if (_instance == null)
_instance = scala.util.Random
_instance
}
}
Upvotes: 0
Reputation: 51693
Try
case class RandomNumberModel() extends Model {
private val rnd = scala.util.Random
def apply(input: String): Double = rnd.nextFloat
override def inputSchema: StructType = StructType("input" -> ScalarType.String).get
override def outputSchema: StructType = StructType("output" -> ScalarType.Double ).get
}
Upvotes: 3