scala lazy val: хороший способ легко собраться на сборщике мусора? - PullRequest
4 голосов
/ 26 октября 2011

Мне интересно, имеет ли смысл использовать lazy val для предотвращения ненужного выделения кучи, тем самым облегчая работу GC.Например, у меня есть привычка писать код так:

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

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

Идея в том, что, делая requiredParameterObject ленивым, я сохраняю выделение кучи в случае, если collection пусто,Но мне интересно: внутренние детали lazy делают это не эффективным выигрышем производительности?

Ответы [ 2 ]

5 голосов
/ 26 октября 2011

Вы можете передать 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 только тогда, когда это необходимо. Однако он будет вызывать столько раз, сколько элементов в коллекции.

3 голосов
/ 26 октября 2011

A аналогичный вопрос был задан здесь некоторое время назад, но кто-то указывает, что реализация lazy варьируется в зависимости от версии компилятора Scala.Вероятно, самый авторитетный ответ, который вы получите на этот вопрос, - написать минимальный фрагмент, например:

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

, запустите его через вашу версию scalac, а затем посмотрите на файл классов с помощью scalapjavap чтобы увидеть, что вы получите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...