【问题标题】:scala lazy val: a good way to go easy on the garbage collector?scala lazy val:在垃圾收集器上轻松的好方法?
【发布时间】:2011-10-26 18:04:19
【问题描述】:

我想知道使用lazy val 来防止不必要的堆分配是否有意义,从而使GC 的工作更容易一些。例如,我有这样写代码的习惯:

lazy val requiredParameterObject = new Foo {
    val a = new ...
    val b = new ...
    // etc
}

for (a <- collection) a.someFunction(requiredParameterObject)

这里的想法是,通过使requiredParameterObject 变得懒惰,我可以在collection 为空的情况下节省堆分配。但我想知道:lazy 的内部细节是否使这不是有效的性能胜利?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以通过姓名传递lazy val

    lazy val requiredParameterObject = new Foo {
        val a = new ...
        val b = new ...
        // etc
    }
    
    class C {
        def someFunction(f: => Foo) {
            f  //(1)
        }
    }
    
    val collection = List(new C, new C)
    for (a <- collection) a.someFunction(requiredParameterObject)
    

    在上面的代码中,Foo 在集合的第一项在 (1) 中访问它时创建一次 - 如果集合为空,则永远不会创建。

    如果requiredParameterObject 是一个普通函数,你也可能会得到更好的结果,只有在需要时才有效地调用requiredParameterObject。但是,它调用它的次数与集合中元素的数量一样多。

    【讨论】:

      【解决方案2】:

      不久前有人问过similar question,但有人指出lazy 的实现因Scala 编译器版本而异。对于这个问题,您可能会得到最权威的答案是编写一个最小的 sn-p,例如:

      def test(pred : Boolean) {
        lazy val v = // ...
        if (pred)
          doSomething(v)
      }
      

      通过你的scalac 版本运行它,然后使用scalapjavap 查看类文件,看看你得到了什么。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-13
        • 2016-11-11
        • 2012-10-06
        • 2012-04-02
        • 2018-12-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多