我有一个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
}
我自然会生成 getGPA
和 getRank
和 getScoreCard
def
s而不是 val
s因为我不希望它们在被使用之前被计算出来 .
如果我将这些方法标记为 lazy val
而不是 def
s会对性能产生什么影响?我想让他们 lazy val
s的原因是:我不想每次为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
这个问题主要针对昂贵的操作中的费用(CPU与内存之间的权衡),以及为什么会提出其他建议?为什么呢?
编辑:感谢您对@ om-nom-nom的评论 . 我应该更清楚我正在寻找什么 .
我在这里读到:
Use of lazy val for caching string representation
缓存对象的字符串表示形式(请参阅@Dave Griffith's answer) . 更确切地说,如果我将它设为 lazy val
而不是 def
,我正在研究垃圾收集的影响
2 回答
对我来说似乎很简单:
然后使用
lazy val
就是这样 .当每个调用的值都可能更改时使用
def
,通常是因为您传递参数,val
将不会更改,但会立即计算 .对于"ordinary"引用类型(例如,
File
),lazy val
具有在第一次计算时创建强引用的效果 . 因此,虽然它将避免重新评估不变的值,但它具有将计算值保持在存储器中的明显成本 .对于原始值(甚至是轻量级对象,如
File
),此内存成本通常不会在内存中持有大量Student
对象 . 但是,对于重要的参考(例如,大型数据结构),您最好使用弱引用,其他一些缓存方法,或者只是按需计算值 .