Scala的懒惰val的(隐藏)成本是多少?

Scala的一个便捷功能是lazy val,其中a的求值val被延迟到必要时(首次访问时)。


当然,lazy val必须有一些开销-Scala必须跟踪某个值是否已经被评估以及评估是否必须同步,因为多个线程可能会尝试同时首次访问该值。


-的确切成本是多少lazy val-是否存在与boolean关联的隐藏布尔标志lazy val以跟踪是否已被评估,确切地同步了什么,还有更多成本吗?


另外,假设我这样做:


class Something {

    lazy val (x, y) = { ... }

}

这与拥有两个单独的lazy vals 是相同的x,y或者对于该对我仅获得一次开销(x, y)吗


翻过高山走不出你
浏览 563回答 3
3回答

慕桂英3389331

这是从scala邮件列表中获取的,并lazy根据Java代码(而非字节码)提供了实现细节:class LazyTest {  lazy val msg = "Lazy"}被编译为等效于以下Java代码的内容:class LazyTest {  public int bitmap$0;  private String msg;  public String msg() {    if ((bitmap$0 & 1) == 0) {        synchronized (this) {            if ((bitmap$0 & 1) == 0) {                synchronized (this) {                    msg = "Lazy";                }            }            bitmap$0 = bitmap$0 | 1;        }    }    return msg;  }}

ITMISS

使用Scala 2.10,像这样的惰性值:class Example {  lazy val x = "Value";}被编译为类似于以下Java代码的字节代码:public class Example {  private String x;  private volatile boolean bitmap$0;  public String x() {    if(this.bitmap$0 == true) {      return this.x;    } else {      return x$lzycompute();    }  }  private String x$lzycompute() {    synchronized(this) {      if(this.bitmap$0 != true) {        this.x = "Value";        this.bitmap$0 = true;      }      return this.x;    }  }}请注意,位图由表示boolean。如果添加另一个字段,则编译器将增加该字段的大小,使其能够表示至少2个值,即表示为byte。这仅适用于大量课程。但是您可能想知道为什么这可行?进入同步块时,必须清除线程本地缓存,以便将非易失性x值刷新到内存中。
打开App,查看更多内容
随时随地看视频慕课网APP