2016年8月11日星期四

Lazy Vals in Scala: A Look Under the Hood

How is this mechanism implemented in Scala? Luckily, we can have a look at SIP-20. The example class LazyCell with a lazy val value is defined as follows:
final class LazyCell {
  lazy val value: Int = 42
}
A handwritten snippet equivalent to the code the compiler generates for our LazyCelllooks like this:
final class LazyCell {
  @volatile var bitmap_0: Boolean = false                   // (1)
  var value_0: Int = _                                      // (2)
  private def value_lzycompute(): Int = {
    this.synchronized {                                     // (3)
      if (!bitmap_0) {                                      // (4)
        value_0 = 42                                        // (5)
        bitmap_0 = true
      }
    }
    value_0
  }
  def value = if (bitmap_0) value_0 else value_lzycompute() // (6)
}
At (3) we can see the use of a monitor this.synchronized {...} in order to guarantee that initialization happens only once, even in a multithreaded scenario. The compiler uses a simple flag ((1)) to track the initialization status ((4) & (6)) of the varvalue_0 ((2)) which holds the actual value and is mutated on first initialization ((5)).
What we can also see in the above implementation is that a lazy val, other than a regular val has to pay the cost of checking the initialization state on each access ((6)). Keep this in mind when you are tempted to (try to) use lazy val as an “optimization”.



没有评论:

发表评论