在案例类中def vs lazy val

时间:2014-07-22 16:41:30

标签: scala lazy-evaluation function

我有一个DAO对象,我将其定义为案例类。

case class StudentDAO(id: Int) {
  def getGPA: Double = // Expensive database lookup goes here
  def getRank: Int = // Another expensive database operation and computation goes here
  def getScoreCard: File = // Expensive file lookup goes here
}

我自然会getGPAgetRank以及getScoreCard def而不是val s,因为我不希望它们在计算之前计算出来可能用过了。

如果我将这些方法标记为lazy val而不是def,会对性能产生什么影响?我想让它们成为lazy val的原因是:我不想每次为id为“i”的学生重新计算排名。

我希望这不会被标记为重复,因为下面有几个问题主要是差异:

When to use val, def, and lazy val in Scala?

def or val or lazy val for grammar rules?

`def` vs `val` vs `lazy val` evaluation in Scala

Scala Lazy Val Question

这个问题主要针对昂贵的操作method lazy val以及其他建议和为什么建议的费用(CPU与内存之间的权衡)?

编辑:感谢您发表评论@ om-nom-nom。我应该更清楚我正在寻找什么。

我在这里读到:

Use of lazy val for caching string representation

缓存对象的字符串表示(请参阅@Dave Griffith's answer)。更准确地说,如果我将其设为lazy val而不是def

,我正在研究垃圾收集的影响

2 个答案:

答案 0 :(得分:8)

对我来说似乎很简单:

  

我不希望它们在可能之前被计算出来   用过的。   [...]   我不想每次为id为#34; i"的学生重新计算等级。

然后使用lazy val即可。

当每个调用的值发生变化时,会使用

def,通常是因为您传递参数,val不会更改,但会立即计算。

答案 1 :(得分:2)

“普通”引用类型的lazy val(例如File)具有在第一次评估时创建强引用的效果。因此,虽然它将避免重新评估不变的值,但它具有将计算值保持在存储器中的明显成本。

对于原始值(甚至是轻量级对象,如File),这个内存成本通常不是问题(除非你在内存中持有大量Student个对象)。但是,对于重要的参考(例如,大型数据结构),您可能最好使用弱引用,其他一些缓存方法,或者只是按需计算值。