【问题标题】:Performance: List containing lots of objects VS lots of objects containing smaller lists性能:包含大量对象的列表 VS 包含较小列表的大量对象
【发布时间】:2017-10-03 20:57:09
【问题描述】:

我目前正在开发自己的应用程序(只是著名的“生命游戏”的另一个翻版),我想添加一个“还原”按钮。我的游戏基本上由一个二维数组组成: Cell[][]... 所以:我的想法是创建一个 ArrayList,该数组被添加到每次更新中......(限制为 50 个条目) 但后来我想,那个列表中会有很多对象......所以:

在二维数组的每个单元格中都有一个包含自身历史的 ArrayList,还是有一个包含整个游戏状态的巨大 ArrayList 作为历史,性能会更好吗?

(我认为你不需要我的任何代码来回答这个问题,但如果你需要,我会发布它)

【问题讨论】:

    标签: java performance arraylist history revert


    【解决方案1】:

    为什么不保存细胞状态,而不是保存改变细胞状态的事件?一个事件将简单地封装前一个状态信息和下一个状态,或者甚至可能是一个可以反向执行的编码枚举。这已经大大减少了您需要存储的数据。

    此外,如果您是在本地工作,还是在垃圾收集 VM 平台(如 Java 或 C#)上工作,这会有所不同。前者往往更快,并且在大型寻址存储方面更宽容,而如果您存储大量对象,后者可能会开始疯狂地丢弃。

    但布丁的真正证据在于吃 / tinstatfc:没有最快的代码 (c) Michael Abrash -> 即对您的代码进行基准测试并找出答案! (来告诉我们)

    【讨论】:

    • 我将如何存储事件?首先:我没有任何事件,但我可以创建一些……其次:如果我想存储它们,那和存储状态不一样吗?
    • 具有单个单元格状态的数组列表只是布尔值列表,所以我认为事件列表不会减少数据
    • 回答你的第二个问题:如果你的所有细胞都在不断变化,是的,但不一定如此。这在一定程度上取决于您的转换规则和状态数据的“丰富程度”。例如,在游戏的基本版本中,许多著名的模式通常只是简单地在多个帧上以固定的动作重复。这也可以用来节省空间。
    • 哦,是的,这听起来很聪明!但仍然:假设我不会将状态放入列表中,而是,如果状态发生变化,我只会添加一个 true,如果没有,我会添加一个 false......它仍然是相同数量的布尔值不会吗?
    • 例如:如果平均每帧在 50x50 场中只有 20 个单元格发生变化,那么仅存储变化的单元格时每帧花费的内存不到 1%,而不是每帧存储 2500 个状态单元格框架。或者,您也可以将棋盘细分为块并使用哈希函数中的位,以便您可以将每个块存储为字符串。您甚至可以使用字典来引用之前已经处于活动状态的块。
    【解决方案2】:

    在我看来,每个单元格一个 ArrayList 可以正常工作;但是,如果您只想存储 50 个状态,则必须创建自定义 ADT 或使用 Guava 的 Collections API。

    我建议使用Stack 而不是ArrayList,因为还原每个单元格将是一个简单的操作。在 Java 中,要使用的正确 ADT 是 ArrayDeque,但您必须自己处理容量。

    【讨论】:

    • 如果最新的状态将是第 50 个(第 100 个/...)一个,我想只删除最旧的状态...或者使用堆栈时有什么真正的优势吗?我以前从未使用过它们
    • 使用Stack 会更容易使用,ArrayDeque 允许您编辑集合的两侧,这意味着您可以添加新元素并同时删除最旧的元素。跨度>
    • 好的,我只是给了每个单元格一个 ArrayList,其中包含表示其状态的布尔值...也许这不是最高效的方法,但它是最简单的,而且它就像一个魅力
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2013-11-09
    相关资源
    最近更新 更多