假设我们构建一个对象来表示一些网络(社交,无线,等等).所以我们有一些'node'对象来表示网络的KIND,不同的节点可能有不同的行为,等等.网络具有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//
}
Run Code Online (Sandbox Code Playgroud)
方法(a)似乎最简单.我的第一个问题是Scala 2.8中这是否代价高昂,第二个问题是它是否违反DRY的原则?
简短回答:过早优化是其中的根源等.使用干净的参考方法.当您遇到性能问题时,无法替代分析和基准测试.
答案很长:Scala使用与Java完全相同的引用机制,因此这比Jala问题更像是一个JVM问题.正式地,JVM规范没有说明如何实现引用.在实践中,它们往往是字大小或更小的指针,指向对象或索引到指向对象的表(后者帮助垃圾收集器).
无论哪种方式,refs数组的大小与32位vm上的int数组大小相同,或者在64bit vm上大约两倍(除非使用压缩oops).这种倍增可能对你很重要,也可能不重要.
如果使用基于ref的方法,则从节点到邻居的每次遍历都是参考间接.使用基于int的方法,从节点到邻居的每次遍历都是查找表,然后是参考间接.因此int方法在计算上更昂贵.这就是假设你将整数放入一个不包含整数的集合中.如果你打算使用int,那么它只是纯粹的疯狂,因为现在你有了与原始AND一样多的引用并且你有一个表查找.
无论如何,如果你使用基于引用的方法,那么额外的引用可以为垃圾收集器做一些额外的工作.如果对节点的唯一引用位于一个数组中,那么gc将快速扫描那个节点.如果它们分散在图表中,那么gc将不得不更加努力地追踪它们.这可能会也可能不会影响您的需求.
从清洁的角度来看,基于ref的方法要好得多.所以一起去,然后剖析一下,看看你在哪里花时间.那个或基准都接近.
归档时间: |
|
查看次数: |
603 次 |
最近记录: |