为了账号安全,请及时绑定邮箱和手机立即绑定

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

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)吗
查看完整描述

3 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

这是从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;

  }


}



查看完整回答
反对 回复 2019-12-12
?
ITMISS

TA贡献1871条经验 获得超8个赞

使用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值刷新到内存中。



查看完整回答
反对 回复 2019-12-12
  • 3 回答
  • 0 关注
  • 557 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信