gpt4 book ai didi

oop - Scala 中对象引用的成本是多少?

转载 作者:行者123 更新时间:2023-12-04 20:03:54 24 4
gpt4 key购买 nike

假设我们构建了一个对象来表示某个网络(社交网络、无线网络等)。所以我们有一些“节点”对象来表示网络的种类,不同的节点可能有不同的行为等等。网络有一个 MutableList 节点。

但是每个节点都有邻居,而这些邻居也是节点。因此,在某个地方,每个节点都必须有一个该节点的所有邻居的列表——或者这样的列表必须在需要时动态生成。如果邻居列表存储在节点对象中,将其存储为 (a) 节点列表或 (b) 可用于引用网络外节点的数字列表是否更便宜?

为了清楚起见,一些代码:

//approach (a)

class network {
val nodes = new MutableList[Node]
// other stuff //
}

class Node {
val neighbors = new MutableList[Node]
// other stuff //
}

//approach (b)
class Network {
val nodes = new MutableList[Node]
val indexed_list = //(some function to get an indexed list off nodes)
//other stuff//
}

class Node {
val neighbors = MutableList[Int]
//other stuff//
}

方法 (a) 似乎是最简单的。我的第一个问题是这在 Scala 2.8 中是否代价高昂,第二个问题是它是否违反了 DRY 原则?

最佳答案

简短的回答:过早的优化是等的根源。使用干净的引用方法。当您遇到性能问题时,分析和基准测试是无可替代的。

长答案:Scala 使用与 Java 完全相同的引用机制,因此这实际上是一个 JVM 问题,而不是 Scala 问题。正式的 JVM 规范没有说明引用是如何实现的。在实践中,它们往往是字长或更小的指针,它们要么指向一个对象,要么指向指向该对象的表(后者有助于垃圾收集器)。

无论哪种方式,refs 数组的大小都与 32 位 vm 上的 int 数组大小相同,或者 64 位 vm 上的大小约为 double(除非使用压缩循环)。加倍可能对您很重要,也可能不重要。

如果您使用基于 ref 的方法,则从节点到邻居的每次遍历都是引用间接。使用基于 int 的方法,从节点到邻居的每次遍历都是对表的查找,然后是引用间接。因此 int 方法的计算成本更高。这是假设您将整数放入不将整数装箱的集合中。如果您确实将整数装箱,那么这只是纯粹的疯狂,因为现在您获得的引用与原始引用一样多,并且您已经获得了表格查找。

无论如何,如果您使用基于引用的方法,那么额外的引用可以为垃圾收集器带来一些额外的工作。如果对节点的唯一引用位于一个数组中,那么 gc 将扫描得非常快。如果它们分散在图表中,那么 gc 将不得不更加努力地追踪它们。这可能会也可能不会影响您的需求。

从清洁的角度来看,基于 ref 的方法要好得多。所以去吧,然后配置文件,看看你在哪里度过你的时间。或者对这两种方法进行基准测试。

关于oop - Scala 中对象引用的成本是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5432246/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com