0

我有一个生成随机数的随机数类。但是我希望它作为类成员启动,这样我们就不需要在每次调用中重新生成。下面是目前的代码。

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

}

我是 scala 的新手,需要建议我必须在这里做些什么改变?

4

3 回答 3

3

尝试

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

}
于 2019-02-18T07:48:34.667 回答
1

这主要是对您自己的答案的回应,但不适合评论。

  1. Scala 有一个内置的和线程安全的替代方案,可以替代您对var _instanceand所做的操作def instance: lazy val。使用它我们得到

    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
    
  2. 由于您在使用时总是需要初始化实例RandomNumberModel,因此实际上您并没有从lazy这种情况下获得任何好处,只有一些小的开销。伴随对象中的非惰性vals 仅在加载类时初始化,例如,当您创建类的第一个实例时。所以就做吧private val instance : Random = scala.util.Random

  3. 您不需要存储始终指向类中相同实例的引用,这只会浪费内存。RandomNumberModel.instance直接使用更好

    case class RandomNumberModel() extends Model{
        def apply(input: String):  Double  = {
            RandomNumberModel.instance.nextFloat // why not nextDouble?
        }
    
        ...
    }
    
  4. 您有多个模型使用相同的Random. 如果您的程序曾经有多个线程操作模型,请注意

    java.util.Random 的实例是线程安全的。但是,跨线程并发使用同一个 java.util.Random 实例可能会遇到争用,从而导致性能下降。

    如果您使用ThreadLocalRandom它处理初始化本身:

    case class RandomNumberModel() extends Model{
        def apply(input: String):  Double  = {
             ThreadLocalRandom.current.nextFloat
        }
    
        ...
    }
    
    // object RandomNumberModel is gone
    
  5. 你希望所有RandomNumberModel的 s 都是平等的吗?如果没有,就不要做case class

于 2019-02-18T09:05:20.560 回答
0

我尝试如下这样可以正常工作还是在这里我做错了什么:

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
  }
}
于 2019-02-18T08:21:24.643 回答