我有一个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
而不是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
这个问题主要针对昂贵的操作method
lazy val
以及其他建议和为什么建议的费用(CPU与内存之间的权衡)?
我在这里读到:
Use of lazy val for caching string representation
缓存对象的字符串表示(请参阅@Dave Griffith's answer)。更准确地说,如果我将其设为lazy val
而不是def
答案 0 :(得分:8)
对我来说似乎很简单:
我不希望它们在可能之前被计算出来 用过的。 [...] 我不想每次为id为#34; i"的学生重新计算等级。
然后使用lazy val
即可。
def
,通常是因为您传递参数,val
不会更改,但会立即计算。
答案 1 :(得分:2)
“普通”引用类型的lazy val
(例如File
)具有在第一次评估时创建强引用的效果。因此,虽然它将避免重新评估不变的值,但它具有将计算值保持在存储器中的明显成本。
对于原始值(甚至是轻量级对象,如File
),这个内存成本通常不是问题(除非你在内存中持有大量Student
个对象)。但是,对于重要的参考(例如,大型数据结构),您可能最好使用弱引用,其他一些缓存方法,或者只是按需计算值。