缓存Scala案例类实例
假设我们有以下案例类:缓存Scala案例类实例,scala,caching,case-class,Scala,Caching,Case Class,假设我们有以下案例类: abstract sealed class Tree case class Leaf(i: Int) extends Tree case class Node(left: Tree, right: Tree) extends Tree 每次调用case类构造函数时,都会在内存中创建一个新对象。例如,在下面的代码中: val a = Leaf(0) val b = Leaf(0) a和b指向内存中不同的对象: a == b // true a eq b // fals
abstract sealed class Tree
case class Leaf(i: Int) extends Tree
case class Node(left: Tree, right: Tree) extends Tree
每次调用case类构造函数时,都会在内存中创建一个新对象。例如,在下面的代码中:
val a = Leaf(0)
val b = Leaf(0)
a和b指向内存中不同的对象:
a == b // true
a eq b // false
我想重写case类的“apply”方法,使它们返回一个缓存对象(如果它已经存在),这样,在上面的最小示例中,“aeq b”将返回true
我在Stackoverflow中找到了这两个相关的答案:
- (显示如何重写“应用”方法)
- (显示缓存案例类实例的简单方法)
abstract sealed class Tree
cached case class Leaf(i: Int) extends Tree
cached case class Node(left: Tree, right: Tree) extends Tree
?
缓存case类的实例似乎是减少内存消耗的一件非常有用和自然的事情
请注意,这甚至不是一个自动的改进,这在很大程度上取决于case类的使用模式(不仅是您的,还取决于使用您的库的任何人):
WeakHashMap
不会有帮助:它要求“值对象不直接或间接地强烈引用它们自己的键”)Leaf
),则在查找之前需要对它们进行装箱,这通常已经是一个构造函数调用但是忽略所有这些,您可以编写一个宏注释,它将允许
@cached-case-class-Leaf(i:Int)扩展树
,并生成所需的代码(或者至少@cached-case-class
;我不确定您是否能够覆盖apply
)。由于上述原因,我不希望它很快成为该语言的一部分。这只是一个随机的问题,您是否见过这种“缓存”作为其他语言的核心功能?至少我还没有遇到它,我也是。这让我想知道是否有这样的原因@Alexey Romanov在下面的回答中指出了一些有趣的原因。总的来说,这些都是好的方面,尽管其中一些不适用于我的特定使用模式。你能详细说明你的第四点吗?我如何知道何时不会构造新对象?我在哪里可以了解更多信息?您能提供一个@cachedcase宏注释的最小示例吗?有关基本解释,请参阅。其思想是,如果一个对象只在一个方法中使用,而没有“转义”,那么可以通过用局部变量替换所有字段来消除它。但检查是否消除了任何特定的分配绝非易事(而且无论如何都需要JIT来启动,所以尝试一次是行不通的)。请参见例如,@cachedcase
示例,您指的是使用还是实现?用法将是@cachedcase类叶(i:Int)扩展树
。实施将需要我目前没有的时间,尤其是要把它做好。谢谢。我指的是实现,而不是使用。但别担心。