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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With