Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala lazy val: a good way to go easy on the garbage collector?

Tags:

scala

I'm wondering if it makes sense to use lazy val to prevent unnecessary heap allocations, thereby making the GC's job a little easier. For instance, I am in the habit of writing code like so:

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

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

The idea here is that by making requiredParameterObject lazy, I am saving a heap allocation in the case that collection is empty. But I am wondering: do the internal details of lazy make this not an effective performance win?

like image 728
Landon Kuhn Avatar asked Feb 22 '23 14:02

Landon Kuhn


2 Answers

You can pass lazy val by name:

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)

In the code above Foo is created once when the first item of a collection accesses it in (1) - or never if the collection is empty.

You might also get better results if requiredParameterObject is an ordinary function, effectively calling requiredParameterObject lazily only when it's needed. However it will call it as many times as the the number of elements in the collection.

like image 53
Tomasz Nurkiewicz Avatar answered Mar 23 '23 18:03

Tomasz Nurkiewicz


A similar question was asked here a while back, but somebody points out there that the implementation of lazy varies between Scala compiler versions. Probably the most authoritative answer you'll get to this question is to write a minimal snippet, like:

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

run it through your version of scalac and then peek at the classfile with scalap or javap to see what you get.

like image 45
mergeconflict Avatar answered Mar 23 '23 17:03

mergeconflict