【问题标题】:Array of Objects or Object with arrays?对象数组还是带有数组的对象?
【发布时间】:2011-08-11 19:25:30
【问题描述】:

我有一个设计选择:我是创建一个包含几个不同值的包装对象数组,还是创建一个包含几个不同值数组的对象?

选项 1:

Node[][] nodes;
class Node{
   double val1;
   double val2;
}

选项 2:

Node[] nodes;
class Node{
    double[] val1;
    double[] val2;
}

我的直觉是,选项 2 会更有效,只是因为对象更少,因此开销也更少,但是 double[] 会不会同样昂贵?

【问题讨论】:

  • 明智的设计,首先考虑 Node 类并以这样一种方式设计它,即变量对整体语义最有意义。然后担心效率。 We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil - Donald Knuth
  • 为什么不为您的阵列创建一个Interface 并让您的阵列实现它,这样,如果由于某种原因一个阵列不符合您的要求,您可以轻松地将其替换为另一个.

标签: java arrays performance


【解决方案1】:

您知道这里会有一个重大问题吗?您要创建多少个?

你不应该太担心一开始的性能——问问自己一个节点逻辑上是有多对值还是只有一对。让您的类遵循您正在建模的内容 - 密切关注性能和内存使用情况,但不要让它支配您的设计而排除自然模型。

【讨论】:

  • 我正在写一个答案...但是我在你的高超知识面前鞠躬。
  • 我不认为这是一个大问题,但无论哪种方式似乎都是一种合理的思维模式,所以我想选择一种更有效的方式。
  • @Andrew:一个可能在建模方面优于另一个 - 但我们对您的领域了解不足,无法在这方面为您提供任何建议.使用愉快的小差异可能比内存使用的小差异更重要:)
【解决方案2】:

内存模型 ->

数组 = value1, value2, value3 ...

对象 = 字段 1、字段 2、字段 3...

如果你有对象数组,内存看起来像:Field1, Field2, Field3, Field1, Field2, Field3...

如果你有一个带有数组的对象,内存看起来像Field1, Field1, Field1.... Field2, Field2, Field2...

访问连续内存比访问非连续内存要快。

【讨论】:

    【解决方案3】:

    如果你有一个 10*20 的数组,则在第一种情况下表示 10*20*2,在第二种情况下表示 10*(20+20)。在这两种情况下,都是 400。所以在内存方面没有区别。

    如果您的数组只包含几个节点,您不妨考虑一个 HashMap,其中 K 是一个不可变类,其中包含给定节点的数组坐标,V 是一个包含该节点的 val1 和 val2 的对象。您只会为每个节点分配内存,而不是为整个数组分配内存。

    【讨论】:

    • 虽然两者都需要 400 个双精度数的空间,但选项 1 将有 200 个节点,而选项 2 将有 20 个节点(第一个数组被移动到里面)。尽管在实践中,数组大小将更接近 [3][1000+]。所以我认为最终它不会有什么不同。谢谢。
    • @Andrew 另一种解决方案是创建两个 10*20 的双精度数组,根本不创建节点。它可以节省更多内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    相关资源
    最近更新 更多